@idem.agency/form-builder 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +922 -12
  2. package/dist/index.cjs +272 -88
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +18 -16
  5. package/dist/index.d.mts +18 -16
  6. package/dist/index.mjs +273 -89
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +5 -2
  9. package/src/index.ts +19 -5
  10. package/CHANGELOG.md +0 -8
  11. package/eslint.config.js +0 -23
  12. package/public/index.html +0 -13
  13. package/public/main.tsx +0 -90
  14. package/src/app/debug.tsx +0 -0
  15. package/src/app/index.tsx +0 -80
  16. package/src/app/test.css +0 -1
  17. package/src/entity/inputs/index.ts +0 -2
  18. package/src/entity/inputs/ui/group/index.tsx +0 -28
  19. package/src/entity/inputs/ui/input/index.tsx +0 -31
  20. package/src/shared/hook/useUpdateEffect.tsx +0 -23
  21. package/src/shared/lib/VisibleCore.spec.ts +0 -103
  22. package/src/shared/lib/VisibleCore.ts +0 -43
  23. package/src/shared/lib/validation/core.spec.ts +0 -103
  24. package/src/shared/lib/validation/core.ts +0 -79
  25. package/src/shared/lib/validation/rules/base.ts +0 -10
  26. package/src/shared/lib/validation/rules/confirm.spec.ts +0 -17
  27. package/src/shared/lib/validation/rules/confirm.ts +0 -32
  28. package/src/shared/lib/validation/rules/email.spec.ts +0 -12
  29. package/src/shared/lib/validation/rules/email.ts +0 -13
  30. package/src/shared/lib/validation/rules/require.spec.ts +0 -13
  31. package/src/shared/lib/validation/rules/require.ts +0 -12
  32. package/src/shared/model/builder/createContext.tsx +0 -40
  33. package/src/shared/model/builder/index.ts +0 -6
  34. package/src/shared/model/index.ts +0 -12
  35. package/src/shared/model/store/createStoreContext.tsx +0 -74
  36. package/src/shared/model/store/index.ts +0 -46
  37. package/src/shared/model/store/store.ts +0 -27
  38. package/src/shared/types/common.ts +0 -79
  39. package/src/shared/utils.ts +0 -25
  40. package/src/widgets/dynamicBuilder/element.tsx +0 -31
  41. package/src/widgets/dynamicBuilder/index.tsx +0 -33
  42. package/tsconfig.json +0 -24
  43. package/tsdown.config.ts +0 -10
  44. package/vite.config.ts +0 -11
package/dist/index.cjs CHANGED
@@ -47,18 +47,29 @@ function createStore(reducer, initialState) {
47
47
  },
48
48
  subscribe(listener) {
49
49
  listeners.add(listener);
50
- return () => listeners.delete(listener);
50
+ return () => {
51
+ listeners.delete(listener);
52
+ };
53
+ },
54
+ subscribeSelector(selector, listener) {
55
+ let prev = selector(state);
56
+ return this.subscribe(() => {
57
+ const next = selector(state);
58
+ if (next !== prev) {
59
+ prev = next;
60
+ listener(next);
61
+ }
62
+ });
51
63
  }
52
64
  };
53
65
  }
54
66
 
55
67
  //#endregion
56
68
  //#region src/shared/model/store/createStoreContext.tsx
57
- function createStoreContext$1(reducer, initialState) {
69
+ function createStoreContext(reducer, defaultState) {
58
70
  const StoreContext = (0, react.createContext)(null);
59
- const Provider = ({ children }) => {
60
- const storeRef = (0, react.useRef)(null);
61
- if (!storeRef.current) storeRef.current = createStore(reducer, initialState);
71
+ const Provider = ({ children, initialState }) => {
72
+ const storeRef = (0, react.useRef)(createStore(reducer, initialState ?? defaultState));
62
73
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StoreContext.Provider, {
63
74
  value: storeRef.current,
64
75
  children
@@ -74,51 +85,56 @@ function createStoreContext$1(reducer, initialState) {
74
85
  if (!store) throw new Error("StoreProvider missing");
75
86
  return store.dispatch;
76
87
  }
77
- function useSubmit(onSubmit) {
88
+ function useStoreInstance() {
78
89
  const store = (0, react.useContext)(StoreContext);
79
- return () => {
80
- if (store) onSubmit(store.getState());
81
- };
90
+ if (!store) throw new Error("StoreProvider missing");
91
+ return store;
82
92
  }
83
93
  return {
84
94
  Provider,
85
95
  useStore,
86
- useSubmit,
87
- useDispatch
96
+ useDispatch,
97
+ useStoreInstance
88
98
  };
89
99
  }
90
100
 
91
101
  //#endregion
92
102
  //#region src/shared/utils.ts
93
103
  function updateNestedValue(obj, path, value) {
94
- if (path.length === 0) return value;
104
+ if (!path) return value;
105
+ return _updateByKeys(obj, path.split("."), value);
106
+ }
107
+ function _updateByKeys(obj, keys, value) {
108
+ if (keys.length === 0) return value;
95
109
  const newObj = Array.isArray(obj) ? [...obj] : { ...obj };
96
- const currentKey = path[0];
97
- if (path.length === 1) newObj[currentKey] = value;
110
+ const currentKey = keys[0];
111
+ if (currentKey === "__proto__" || currentKey === "constructor" || currentKey === "prototype") throw new Error(`Forbidden path key: ${currentKey}`);
112
+ if (keys.length === 1) newObj[currentKey] = value;
98
113
  else {
99
- const remainingPath = path.slice(1);
114
+ const remainingKeys = keys.slice(1);
100
115
  const nestedObj = newObj[currentKey];
101
- if (typeof nestedObj === "undefined" || nestedObj === null) newObj[currentKey] = typeof remainingPath[0] === "number" ? [] : {};
102
- newObj[currentKey] = updateNestedValue(newObj[currentKey], remainingPath, value);
116
+ if (typeof nestedObj === "undefined" || nestedObj === null) newObj[currentKey] = typeof remainingKeys[0] === "number" ? [] : {};
117
+ newObj[currentKey] = _updateByKeys(newObj[currentKey], remainingKeys, value);
103
118
  }
104
119
  return newObj;
105
120
  }
106
121
  function getNestedValue(obj, path) {
107
- return path.reduce((acc, key) => acc && acc[key] !== void 0 ? acc[key] : void 0, obj);
122
+ if (!path) return obj;
123
+ return path.split(".").reduce((acc, key) => acc && acc[key] !== void 0 ? acc[key] : void 0, obj);
108
124
  }
109
125
 
110
126
  //#endregion
111
- //#region src/shared/model/store/index.ts
112
- const initialState = {
113
- formData: {},
114
- errors: {}
115
- };
127
+ //#region src/shared/model/store/index.tsx
116
128
  function reducer(state, action) {
117
129
  const newData = { ...state };
118
130
  switch (action.type) {
119
131
  case "setValue":
120
132
  newData.formData = updateNestedValue(newData.formData, action.path, action.value);
121
133
  break;
134
+ case "setFieldValue":
135
+ newData.formData = updateNestedValue(newData.formData, action.path, action.value);
136
+ newData.errors = updateNestedValue(newData.errors, action.path, action?.errors?.length ? action.errors : null);
137
+ break;
122
138
  case "setError":
123
139
  newData.errors = updateNestedValue(newData.errors, action.path, action.value);
124
140
  break;
@@ -132,106 +148,262 @@ function reducer(state, action) {
132
148
  }
133
149
  return newData;
134
150
  }
135
- const { Provider: FormStoreProvider, useStore: useFormStore, useDispatch: useFormDispatch, useSubmit } = createStoreContext$1(reducer, initialState);
151
+ const { Provider, useStore: useFormStore, useDispatch: useFormDispatch, useStoreInstance: useFormStoreInstance } = createStoreContext(reducer, {
152
+ formData: {},
153
+ errors: {}
154
+ });
155
+ const FormStoreProvider = ({ children, formData }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Provider, {
156
+ initialState: {
157
+ formData: formData ?? {},
158
+ errors: {}
159
+ },
160
+ children
161
+ });
162
+
163
+ //#endregion
164
+ //#region src/plugins/validation/rules/confirm.ts
165
+ const confirm = {
166
+ code: "confirm",
167
+ fn: (value, data, args) => {
168
+ const attr = args[0] ?? false;
169
+ return attr ? value == getNestedValue(data, attr) : false;
170
+ },
171
+ message: "Поле не совпадает с ::attr(1)"
172
+ };
173
+
174
+ //#endregion
175
+ //#region src/plugins/validation/rules/required.ts
176
+ const required = {
177
+ code: "required",
178
+ fn: (value) => {
179
+ return value !== void 0 && value !== null && value.length > 0;
180
+ },
181
+ message: "Поле обязательно для заполнения"
182
+ };
183
+
184
+ //#endregion
185
+ //#region src/plugins/validation/rules/email.ts
186
+ const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
187
+ const email = {
188
+ code: "email",
189
+ fn: (value) => {
190
+ return emailRegex.test(value);
191
+ },
192
+ message: "Поле не является email"
193
+ };
194
+
195
+ //#endregion
196
+ //#region src/plugins/validation/rules/index.ts
197
+ var rules_default = [
198
+ confirm,
199
+ required,
200
+ email
201
+ ];
202
+
203
+ //#endregion
204
+ //#region src/plugins/validation/validation.ts
205
+ var Validation = class {
206
+ registry = [];
207
+ registerFields = {};
208
+ constructor(onSubmit, rules = []) {
209
+ this.onSubmit = onSubmit;
210
+ this.registry = [...rules, ...rules_default];
211
+ }
212
+ validateRule(rule, data, formData) {
213
+ const [code, rawArgs] = rule.split(":");
214
+ const args = rawArgs ? rawArgs.split(",") : [];
215
+ const userRule = this.registry.find((i) => i.code == code);
216
+ if (!userRule) return null;
217
+ return !userRule.fn(data, formData, args) ? this.replaceMessageArgs(userRule.message, args) : null;
218
+ }
219
+ replaceMessageArgs(message, args = []) {
220
+ const replaceArgs = args.reduce((acc, arg, index) => {
221
+ acc[`::attr(${index})`] = arg;
222
+ return acc;
223
+ }, {});
224
+ return message.replace(/::attr\(\d\)/g, (i) => replaceArgs[i]);
225
+ }
226
+ registerField(path, validators) {
227
+ this.registerFields[path] = validators;
228
+ }
229
+ _validate(rules, data, formData) {
230
+ return rules.map((rule) => {
231
+ return this.validateRule(rule, data, formData);
232
+ }).filter((i) => i !== null);
233
+ }
234
+ validate(rules, data, formData) {
235
+ return !this.onSubmit ? this._validate(rules, data, formData) : [];
236
+ }
237
+ validateAll(formData) {
238
+ return Object.entries(this.registerFields).reduce((acc, [path, rules]) => {
239
+ const value = getNestedValue(formData, path);
240
+ const validationMessage = this._validate(rules, value, formData);
241
+ if (validationMessage.length) acc[path] = validationMessage;
242
+ return acc;
243
+ }, {});
244
+ }
245
+ };
246
+
247
+ //#endregion
248
+ //#region src/plugins/validation/provider.tsx
249
+ function createValidationProvider() {
250
+ const Context = (0, react.createContext)(null);
251
+ const Provider = ({ validator = {
252
+ onSubmit: false,
253
+ rules: []
254
+ }, children }) => {
255
+ const core = (0, react.useMemo)(() => new Validation(validator.onSubmit ?? false, validator.rules ?? []), [validator]);
256
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Context.Provider, {
257
+ value: core,
258
+ children
259
+ });
260
+ };
261
+ const useValidate = (rules) => {
262
+ const core = (0, react.useContext)(Context);
263
+ if (!core) throw new Error("ValidationProvider missing");
264
+ return (data, formData) => {
265
+ return core.validate(rules ?? [], data, formData);
266
+ };
267
+ };
268
+ const useRegister = (currentFieldPath, field) => {
269
+ const core = (0, react.useContext)(Context);
270
+ if (!core) throw new Error("ValidationProvider missing");
271
+ core.registerField(currentFieldPath, field.validation ?? []);
272
+ return useValidate(field.validation);
273
+ };
274
+ const useSubmitValidation = () => {
275
+ const core = (0, react.useContext)(Context);
276
+ if (!core) throw new Error("ValidationProvider missing");
277
+ return (formData) => core.validateAll(formData);
278
+ };
279
+ return {
280
+ Provider,
281
+ useRegister,
282
+ useSubmitValidation
283
+ };
284
+ }
285
+
286
+ //#endregion
287
+ //#region src/plugins/validation/index.ts
288
+ const { Provider: ValidationProvider, useRegister, useSubmitValidation } = createValidationProvider();
136
289
 
137
290
  //#endregion
138
- //#region src/widgets/dynamicBuilder/element.tsx
139
- const BuilderElement = (props) => {
291
+ //#region src/entity/dynamicBuilder/element.tsx
292
+ const DynamicBuilderElement = (props) => {
140
293
  const Element = props.element;
141
294
  const field = props.field;
142
- const currentFieldPath = [...props.path, field.name];
295
+ const currentFieldPath = props.path ? `${props.path}.${field.name}` : field.name;
143
296
  const value = useFormStore(((s) => getNestedValue(s.formData, currentFieldPath)));
144
- const errors = useFormStore(((s) => getNestedValue(s.errors, currentFieldPath)));
297
+ const errors = useFormStore(((s) => s.errors[currentFieldPath]));
145
298
  const dispatch = useFormDispatch();
299
+ const store = useFormStoreInstance();
300
+ const validator = useRegister(currentFieldPath, field);
146
301
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Element, {
147
302
  field: { ...field },
148
- builder: props.DynamicBuilder,
149
303
  path: currentFieldPath,
150
- plugins: props.plugins,
151
304
  value,
152
305
  errors,
153
306
  onChange: (value) => {
307
+ const data = store.getState().formData;
154
308
  dispatch({
155
- type: "setValue",
309
+ type: "setFieldValue",
156
310
  path: currentFieldPath,
157
- value
158
- });
159
- dispatch({
160
- type: "setError",
161
- path: currentFieldPath,
162
- value: ""
311
+ value,
312
+ errors: validator(value, data)
163
313
  });
164
314
  }
165
315
  });
166
316
  };
167
317
 
168
318
  //#endregion
169
- //#region src/widgets/dynamicBuilder/index.tsx
170
- const DynamicBuilder = (props) => {
171
- const path = props.path ?? [];
172
- return props.layout.map((field, index) => {
173
- const FormElement = props.plugins[field.type];
174
- if (!FormElement) {
175
- console.warn(`Неизвестный тип поля: ${field.type}. Проверьте formRegistry.`);
176
- return null;
177
- }
178
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BuilderElement, {
179
- element: FormElement,
180
- path,
181
- field
182
- }, `${field.name}${index}`);
183
- });
184
- };
185
-
186
- //#endregion
187
- //#region src/shared/model/builder/createContext.tsx
188
- function createStoreContext() {
319
+ //#region src/entity/dynamicBuilder/model/createBuilderContext.tsx
320
+ function createBuilderContext() {
189
321
  const BuilderContext = (0, react.createContext)(null);
190
- const Provider = ({ plugins, children }) => {
191
- const storeRef = (0, react.useRef)(null);
192
- if (!storeRef.current) storeRef.current = (layout, path, children) => {
322
+ const Provider = ({ fields, children }) => {
323
+ const builder = (0, react.useCallback)((layout, path, children) => {
193
324
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicBuilder, {
194
325
  layout,
195
326
  path,
196
- plugins,
197
327
  children
198
328
  });
199
- };
329
+ }, [fields]);
200
330
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BuilderContext.Provider, {
201
- value: storeRef.current,
331
+ value: {
332
+ builder,
333
+ fields
334
+ },
202
335
  children
203
336
  });
204
337
  };
205
338
  function useBuilder() {
206
339
  const store = (0, react.useContext)(BuilderContext);
207
340
  if (!store) throw new Error("StoreProvider missing");
208
- return store;
341
+ return store.builder;
342
+ }
343
+ function useFields() {
344
+ const store = (0, react.useContext)(BuilderContext);
345
+ if (!store) throw new Error("StoreProvider missing");
346
+ return store.fields;
209
347
  }
210
348
  return {
211
349
  Provider,
212
- useBuilder
350
+ useBuilder,
351
+ useFields
213
352
  };
214
353
  }
215
354
 
216
355
  //#endregion
217
- //#region src/shared/model/builder/index.ts
218
- const { Provider: BuilderProvider, useBuilder } = createStoreContext();
356
+ //#region src/entity/dynamicBuilder/model/index.ts
357
+ const { Provider: BuilderProvider, useBuilder, useFields } = createBuilderContext();
219
358
 
220
359
  //#endregion
221
- //#region src/app/index.tsx
222
- const FormBuilder = (0, react.forwardRef)((props, ref) => {
223
- const submitHdl = useSubmit((data) => {
224
- if (props.onSubmit) props.onSubmit(data);
360
+ //#region src/entity/dynamicBuilder/index.tsx
361
+ const DynamicBuilder = (props) => {
362
+ const path = props.path ?? "";
363
+ const fields = useFields();
364
+ return props.layout.map((field, index) => {
365
+ const FormElement = fields[field.type];
366
+ if (!FormElement) {
367
+ console.warn(`Неизвестный тип поля: ${field.type}. Проверьте formRegistry.`);
368
+ return null;
369
+ }
370
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicBuilderElement, {
371
+ element: FormElement,
372
+ path,
373
+ field
374
+ }, `${field.name}-${index}`);
225
375
  });
226
- (0, react.useImperativeHandle)(ref, () => ({
227
- reset: () => {},
228
- submit: () => {
229
- submitHdl();
230
- },
231
- errors: () => {
232
- return {};
376
+ };
377
+
378
+ //#endregion
379
+ //#region src/widgets/form/form.tsx
380
+ const Form = (0, react.forwardRef)((props, ref) => {
381
+ const dispatch = useFormDispatch();
382
+ const store = useFormStoreInstance();
383
+ const changeRef = (0, react.useRef)(props.onChange);
384
+ (0, react.useEffect)(() => {
385
+ return store.subscribeSelector((s) => s.formData, (formData) => changeRef.current?.(formData));
386
+ }, [store]);
387
+ const validation = useSubmitValidation();
388
+ const submitHdl = (0, react.useCallback)(() => {
389
+ if (props.onSubmit) {
390
+ const errors = validation(store.getState().formData);
391
+ if (Object.keys(errors).length == 0) props.onSubmit(store.getState().formData);
392
+ else dispatch({
393
+ type: "setErrors",
394
+ errors
395
+ });
233
396
  }
234
- }), [props.onSubmit]);
397
+ }, [props.onSubmit, validation]);
398
+ (0, react.useImperativeHandle)(ref, () => ({
399
+ reset: () => dispatch({ type: "reset" }),
400
+ submit: () => submitHdl(),
401
+ errors: () => store.getState().errors
402
+ }), [
403
+ submitHdl,
404
+ dispatch,
405
+ store
406
+ ]);
235
407
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
236
408
  onSubmit: (e) => {
237
409
  e.preventDefault();
@@ -239,13 +411,10 @@ const FormBuilder = (0, react.forwardRef)((props, ref) => {
239
411
  },
240
412
  className: props?.className,
241
413
  children: [
242
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FormStoreProvider, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BuilderProvider, {
243
- plugins: props.plugins,
244
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicBuilder, {
245
- layout: props.layout,
246
- plugins: props.plugins
247
- })
248
- }) }),
414
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BuilderProvider, {
415
+ fields: props.fields,
416
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicBuilder, { layout: props.layout })
417
+ }),
249
418
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
250
419
  type: "submit",
251
420
  style: { display: "none" }
@@ -255,6 +424,22 @@ const FormBuilder = (0, react.forwardRef)((props, ref) => {
255
424
  });
256
425
  });
257
426
 
427
+ //#endregion
428
+ //#region src/app/index.tsx
429
+ const FormBuilder = (0, react.forwardRef)((props, ref) => {
430
+ const { formData, ...innerProps } = props;
431
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FormStoreProvider, {
432
+ formData,
433
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ValidationProvider, {
434
+ validator: props.validator,
435
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Form, {
436
+ ...innerProps,
437
+ ref
438
+ })
439
+ })
440
+ });
441
+ });
442
+
258
443
  //#endregion
259
444
  //#region src/entity/inputs/ui/input/index.tsx
260
445
  function isTextFieldConfig(field) {
@@ -296,7 +481,7 @@ const TextField = ({ field, value, errors, onChange }) => {
296
481
  //#endregion
297
482
  //#region src/entity/inputs/ui/group/index.tsx
298
483
  function isGroupConfig(field) {
299
- return field.fields;
484
+ return Array.isArray(field.fields);
300
485
  }
301
486
  const FormGroup = ({ field, path }) => {
302
487
  if (!isGroupConfig(field)) return null;
@@ -307,7 +492,6 @@ const FormGroup = ({ field, path }) => {
307
492
  children: Builder
308
493
  })] });
309
494
  };
310
- FormGroup.fieldProps = ["fields"];
311
495
 
312
496
  //#endregion
313
497
  //#region src/shared/model/index.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["createStoreContext","createStoreContext","z"],"sources":["../src/shared/model/store/store.ts","../src/shared/model/store/createStoreContext.tsx","../src/shared/utils.ts","../src/shared/model/store/index.ts","../src/widgets/dynamicBuilder/element.tsx","../src/widgets/dynamicBuilder/index.tsx","../src/shared/model/builder/createContext.tsx","../src/shared/model/builder/index.ts","../src/app/index.tsx","../src/entity/inputs/ui/input/index.tsx","../src/entity/inputs/ui/group/index.tsx","../src/shared/model/index.ts"],"sourcesContent":["export type Reducer<S, A> = (state: S, action: A) => S;\n\nexport function createStore<S, A>(\n reducer: Reducer<S, A>,\n initialState: S\n) {\n let state = initialState;\n const listeners = new Set<() => void>();\n \n return {\n getState(): S {\n return state;\n },\n \n dispatch(action: A) {\n state = reducer(state, action);\n listeners.forEach(l => l());\n },\n \n subscribe(listener: () => void) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n }\n };\n}\n\nexport type Store<S, A> = ReturnType<typeof createStore<S, A>>;\n","import {\n createContext,\n useContext,\n useRef,\n useSyncExternalStore\n} from \"react\";\nimport { createStore, type Reducer, type Store } from \"./store\";\n\nexport function createStoreContext<S, A>(\n reducer: Reducer<S, A>,\n initialState: S\n) {\n const StoreContext = createContext<Store<S, A> | null>(null);\n \n const Provider: React.FC<{ children: React.ReactNode }> = ({\n children\n }) => {\n const storeRef = useRef<Store<S, A>>(null);\n \n if (!storeRef.current) {\n storeRef.current = createStore(reducer, initialState);\n }\n\n return (\n <StoreContext.Provider value={storeRef.current}>\n {children}\n </StoreContext.Provider>\n );\n };\n \n function useStore<T>(\n selector: (state: S) => T\n ): T {\n const store = useContext(StoreContext);\n\n if (!store) {\n throw new Error(\"StoreProvider missing\");\n }\n \n return useSyncExternalStore(\n store.subscribe,\n () => selector(store.getState()),\n () => selector(store.getState())\n );\n }\n \n function useDispatch() {\n const store = useContext(StoreContext);\n \n if (!store) {\n throw new Error(\"StoreProvider missing\");\n }\n \n return store.dispatch;\n }\n \n function useSubmit(onSubmit: (state: S) => void) {\n const store = useContext(StoreContext);\n \n return () => {\n if (store) {\n const state = store.getState();\n onSubmit(state);\n }\n };\n }\n \n return {\n Provider,\n useStore,\n useSubmit,\n useDispatch\n };\n}\n","export function updateNestedValue(obj: any, path: string[], value: any): any {\n if (path.length === 0) {\n return value;\n }\n \n const newObj = Array.isArray(obj) ? [...obj] : { ...obj }; // Создаем копию\n const currentKey = path[0];\n \n if (path.length === 1) {\n // Последний элемент пути, просто обновляем значение\n newObj[currentKey] = value;\n } else {\n const remainingPath = path.slice(1);\n const nestedObj = newObj[currentKey];\n \n if (typeof nestedObj === 'undefined' || nestedObj === null) {\n newObj[currentKey] = typeof remainingPath[0] === 'number' ? [] : {};\n }\n newObj[currentKey] = updateNestedValue(newObj[currentKey], remainingPath, value);\n }\n return newObj;\n}\nexport function getNestedValue(obj: any, path: string[]): any {\n return path.reduce((acc, key) => (acc && acc[key] !== undefined ? acc[key] : undefined), obj);\n}\n","import { createStoreContext } from \"./createStoreContext\";\nimport type {FormData} from \"@/shared/types/common\";\nimport {updateNestedValue} from \"@/shared/utils\";\n\ntype State = {\n formData: FormData\n errors: Record<string, any>\n};\n\ntype Action =\n | { type: \"setValue\"; path: string[]; value: unknown }\n | { type: \"setError\"; path: string[]; value?: string }\n | { type: \"reset\"; }\n | { type: \"setErrors\"; errors?: object };\n\nconst initialState: State = {\n formData: {},\n errors: {}\n};\n\nfunction reducer(state: State, action: Action): State {\n const newData = {...state};\n switch (action.type) {\n case 'setValue':\n newData.formData = updateNestedValue(newData.formData, action.path, action.value);\n break;\n case 'setError':\n newData.errors = updateNestedValue(newData.errors, action.path, action.value);\n break;\n case 'reset':\n newData.formData = {};\n newData.errors = {};\n break;\n case 'setErrors':\n newData.errors = {...action.errors};\n break;\n }\n return newData;\n}\n\nexport const {\n Provider: FormStoreProvider,\n useStore: useFormStore,\n useDispatch: useFormDispatch,\n useSubmit,\n} = createStoreContext(reducer, initialState);\n","import {useFormStore, useFormDispatch} from \"@/shared/model/store\";\nimport {getNestedValue} from \"@/shared/utils\";\n\nexport const BuilderElement = (props: any) => {\n const Element = props.element;\n const field = props.field;\n const currentFieldPath = [...props.path, field.name];\n const value = useFormStore((s=> getNestedValue(s.formData, currentFieldPath)));\n const errors = useFormStore((s=> getNestedValue(s.errors, currentFieldPath)));\n const dispatch= useFormDispatch();\n return <Element\n field={{...field}}\n builder={props.DynamicBuilder}\n path={currentFieldPath}\n plugins={props.plugins}\n value={value}\n errors={errors}\n onChange={(value: any) => {\n dispatch({\n type: 'setValue',\n path: currentFieldPath,\n value\n });\n dispatch({\n type: 'setError',\n path: currentFieldPath,\n value: ''\n });\n }}\n />;\n}\n","import type {TDynamicBuilder} from \"@/shared/types/common\";\nimport {BuilderElement} from \"@/widgets/dynamicBuilder/element\";\n// import {getNestedValue} from \"@/shared/utils\";\n// import {useCallback} from \"react\";\n// import {VisibleCore} from \"@/shared/lib/VisibleCore\";\n// import {use} from \"@/shared/model/store\";\n\nexport const DynamicBuilder: TDynamicBuilder = (props) => {\n const path = props.path ?? [];\n \n // const isShow = useCallback((field: FormFieldConfig) => {\n // let result = true;\n //\n // if (field.viewConfig) {\n // result = VisibleCore.isVisible(field.viewConfig, state.formData);\n // }\n // return result;\n // }, [state]);\n \n \n return props.layout.map((field, index) => {\n const FormElement = props.plugins[field.type];\n \n if (!FormElement) {\n console.warn(`Неизвестный тип поля: ${field.type}. Проверьте formRegistry.`);\n return null;\n }\n \n // const currentValue = getNestedValue(state.formData, currentFieldPath);\n // const currentErrors = getNestedValue(state.errors, currentFieldPath) as (Record<string, string> | undefined);\n return <BuilderElement key={`${field.name}${index}`} element={FormElement} path={path} field={field}/>\n })\n}\n","import React, {createContext, type ReactNode, useContext, useRef,} from \"react\";\nimport {DynamicBuilder} from \"@/widgets/dynamicBuilder\";\n\nexport function createStoreContext() {\n const BuilderContext = createContext<((layout: any, path: string[]|undefined, children?: ReactNode) => ReactNode) | null>(null);\n \n const Provider: React.FC<{ children: React.ReactNode, plugins: any }> = ({\n plugins,\n children\n }) => {\n const storeRef = useRef<(layout: any, path: string[]|undefined, children?: ReactNode) => ReactNode>(null);\n \n if (!storeRef.current) {\n storeRef.current = (layout: any, path: string[]|undefined, children?: ReactNode) => {\n return <DynamicBuilder layout={layout} path={path} plugins={plugins}>{children}</DynamicBuilder>\n };\n }\n \n return (\n <BuilderContext.Provider value={storeRef.current}>\n {children}\n </BuilderContext.Provider>\n );\n };\n \n function useBuilder(): (layout: any, path: string[]|undefined, children?: ReactNode) => ReactNode {\n const store = useContext(BuilderContext);\n \n if (!store) {\n throw new Error(\"StoreProvider missing\");\n }\n \n return store\n }\n \n return {\n Provider,\n useBuilder\n };\n}\n","import {createStoreContext} from \"@/shared/model/builder/createContext\";\n\nexport const {\n Provider: BuilderProvider,\n useBuilder,\n} = createStoreContext();\n","'use client';\n\nimport type {FormBuilderRef, TFormBuilder} from \"../shared/types/common\";\n// import {StoreContext, storeReducer,} from \"@/shared/model\";\n\nimport {DynamicBuilder} from \"../widgets/dynamicBuilder\";\nimport { forwardRef, useImperativeHandle} from \"react\";\n// import {ValidationCore} from \"@/shared/lib/validation/core\";\n// import { useUpdateEffect } from '@/shared/hook/useUpdateEffect';\nimport {FormStoreProvider, useSubmit} from \"@/shared/model/store\";\nimport {BuilderProvider} from \"@/shared/model/builder\";\n\nexport const FormBuilder = forwardRef<FormBuilderRef, TFormBuilder>((props, ref) => {\n // const validator = useMemo(() => {\n // return (new ValidationCore(props.layout, props.plugins))\n // }, [props.layout, props.plugins]);\n\n // const [state, dispatch] = useReducer(storeReducer, {\n // formData: props.formData ?? {},\n // errors: {},\n // });\n //\n // useUpdateEffect(() => {\n // if (props.onChange) {\n // props.onChange(state.formData);\n // }\n // }, [state.formData, props.onChange]);\n const submitHdl = useSubmit((data) => {\n if (props.onSubmit) {\n props.onSubmit(data);\n }\n });\n \n // const submit = () => {\n //\n // // const errors = validator.validate(state.formData);\n // // if (Object.keys(errors).length == 0) {\n // // if (props.onSubmit) {\n // // props.onSubmit(state.formData)\n // // }\n // // } else {\n // // dispatch({\n // // type: 'setErrors',\n // // payload: {\n // // errors\n // // }\n // // });\n // // }\n // }\n\n useImperativeHandle(ref, () => ({\n reset: () => {\n // dispatch({type: 'reset'})\n },\n submit: () => {\n submitHdl();\n },\n errors: () => {\n return {}\n // return state?.errors ?? {};\n }\n }), [props.onSubmit]);\n\n return <form onSubmit={(e) => {\n e.preventDefault();\n submitHdl();\n }}\n className={props?.className}\n >\n <FormStoreProvider>\n <BuilderProvider plugins={props.plugins}>\n <DynamicBuilder layout={props.layout} plugins={props.plugins} />\n </BuilderProvider>\n </FormStoreProvider>\n <input type=\"submit\" style={{ display: 'none' }}/>\n {props.children}\n </form>\n});\n\nexport default FormBuilder;\n","import type { FormElementProps, FormFieldConfig, FormFieldBase, RC } from '../../../../shared/types/common';\nimport { useId } from \"react\";\n\nexport type TextFieldConfig = FormFieldBase & { type: 'text' | 'email' | 'password'; placeholder?: string; };\n\nfunction isTextFieldConfig(field: FormFieldConfig): field is TextFieldConfig {\n return field.type === 'text' || field.type === 'email' || field.type === 'password';\n}\n\nexport const TextField: RC<FormElementProps> = ({ field, value, errors, onChange }) => {\n if (!isTextFieldConfig(field)) {\n console.warn(`TextField received an invalid field config for type: ${field.type}`);\n return null;\n }\n const id = useId();\n return (\n <div style={{ marginBottom: '15px' }}>\n <label htmlFor={id}>{field.label}:</label>\n <input\n type={field.type}\n id={id}\n name={field.name}\n placeholder={field.placeholder}\n value={value || ''}\n onChange={(e) => onChange(e.target.value)}\n style={{ borderColor: errors ? 'red' : '#ccc' }}\n />\n {errors && <p style={{ color: 'red', fontSize: '0.8em' }}>{Object.values(errors).join(', ')}</p>}\n </div>\n );\n};\n","import type {FormElementProps, FormFieldBase, FormFieldConfig, RC} from \"../../../../shared/types/common.ts\";\nimport clsx from \"clsx\";\nimport {useBuilder} from \"@/shared/model/builder\";\nexport type FormGroupConfig = FormFieldBase & { variant?: 'row' | 'col', fields: FormFieldConfig[] };\n\nfunction isGroupConfig(field: FormFieldConfig): field is FormGroupConfig {\n return field.fields;\n}\n\n\nexport const FormGroup: RC<FormElementProps<FormGroupConfig>> = ({field, path}) => {\n if (!isGroupConfig(field)) {\n return null;\n }\n const Builder = useBuilder()(field.fields, path);\n const variant = field.variant ?? 'col';\n \n const className = variant == 'col' ? 'flex-col' : 'flex-row';\n\n return <div>\n <div>{field.label}</div>\n <div className={clsx(className, 'flex')}>\n {Builder}\n </div>\n </div>;\n};\n\nFormGroup.fieldProps = ['fields'];\n","import { z } from 'zod';\n\nconst fieldShema = z.object({\n name: z.string(),\n label: z.string().optional(),\n type: z.string(),\n});\n\ntype TField = z.infer<typeof fieldShema>;\n\nexport type { TField };\nexport { fieldShema };\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["base","z"],"sources":["../src/shared/model/store/store.ts","../src/shared/model/store/createStoreContext.tsx","../src/shared/utils.ts","../src/shared/model/store/index.tsx","../src/plugins/validation/rules/confirm.ts","../src/plugins/validation/rules/required.ts","../src/plugins/validation/rules/email.ts","../src/plugins/validation/rules/index.ts","../src/plugins/validation/validation.ts","../src/plugins/validation/provider.tsx","../src/plugins/validation/index.ts","../src/entity/dynamicBuilder/element.tsx","../src/entity/dynamicBuilder/model/createBuilderContext.tsx","../src/entity/dynamicBuilder/model/index.ts","../src/entity/dynamicBuilder/index.tsx","../src/widgets/form/form.tsx","../src/app/index.tsx","../src/entity/inputs/ui/input/index.tsx","../src/entity/inputs/ui/group/index.tsx","../src/shared/model/index.ts"],"sourcesContent":["export type Reducer<S, A> = (state: S, action: A) => S;\n\nexport function createStore<S, A>(\n reducer: Reducer<S, A>,\n initialState: S\n) {\n let state = initialState;\n const listeners = new Set<() => void>();\n \n return {\n getState(): S {\n return state;\n },\n \n dispatch(action: A) {\n state = reducer(state, action);\n listeners.forEach(l => l());\n },\n \n subscribe(listener: () => void) {\n listeners.add(listener);\n return () => { listeners.delete(listener) };\n },\n\n subscribeSelector<T>(selector: (state: S) => T, listener: (value: T) => void) {\n let prev = selector(state);\n return this.subscribe(() => {\n const next = selector(state);\n if (next !== prev) {\n prev = next;\n listener(next);\n }\n });\n }\n };\n}\n\nexport type Store<S, A> = ReturnType<typeof createStore<S, A>>;\n","import {\n createContext,\n useContext,\n useRef,\n useSyncExternalStore\n} from \"react\";\n\nimport { createStore, type Reducer, type Store } from \"./store\";\n\nexport function createStoreContext<S, A>(\n reducer: Reducer<S, A>,\n defaultState: S\n) {\n const StoreContext = createContext<Store<S, A> | null>(null);\n const Provider: React.FC<{ children: React.ReactNode, initialState?: S }> = ({\n children,\n initialState\n }) => {\n const storeRef = useRef<Store<S, A>>(createStore(reducer, initialState ?? defaultState));\n\n return (\n <StoreContext.Provider value={storeRef.current}>\n {children}\n </StoreContext.Provider>\n );\n };\n \n function useStore<T>(\n selector: (state: S) => T\n ): T {\n const store = useContext(StoreContext);\n\n if (!store) {\n throw new Error(\"StoreProvider missing\");\n }\n \n return useSyncExternalStore(\n store.subscribe,\n () => selector(store.getState()),\n () => selector(store.getState())\n );\n }\n \n function useDispatch() {\n const store = useContext(StoreContext);\n \n if (!store) {\n throw new Error(\"StoreProvider missing\");\n }\n \n return store.dispatch;\n }\n \n function useStoreInstance(): Store<S, A> {\n const store = useContext(StoreContext);\n\n if (!store) {\n throw new Error(\"StoreProvider missing\");\n }\n\n return store;\n }\n \n return {\n Provider,\n useStore,\n useDispatch,\n useStoreInstance,\n };\n}\n","export function updateNestedValue(obj: any, path: string, value: any): any {\n if (!path) return value;\n return _updateByKeys(obj, path.split('.'), value);\n}\n\nfunction _updateByKeys(obj: any, keys: string[], value: any): any {\n if (keys.length === 0) return value;\n\n const newObj = Array.isArray(obj) ? [...obj] : { ...obj };\n const currentKey = keys[0];\n\n if (currentKey === '__proto__' || currentKey === 'constructor' || currentKey === 'prototype') {\n throw new Error(`Forbidden path key: ${currentKey}`);\n }\n\n if (keys.length === 1) {\n newObj[currentKey] = value;\n } else {\n const remainingKeys = keys.slice(1);\n const nestedObj = newObj[currentKey];\n\n if (typeof nestedObj === 'undefined' || nestedObj === null) {\n newObj[currentKey] = typeof remainingKeys[0] === 'number' ? [] : {};\n }\n newObj[currentKey] = _updateByKeys(newObj[currentKey], remainingKeys, value);\n }\n return newObj;\n}\n\nexport function getNestedValue(obj: any, path: string): any {\n if (!path) return obj;\n return path.split('.').reduce(\n (acc, key) => (acc && acc[key] !== undefined ? acc[key] : undefined),\n obj\n );\n}\n","import { createStoreContext } from \"./createStoreContext\";\nimport type {FormData} from \"@/shared/types/common\";\nimport {updateNestedValue} from \"@/shared/utils\";\nimport type {Provider, ReactNode} from \"react\";\n\ntype State = {\n formData: FormData\n errors: Record<string, any>\n};\n\ntype Action =\n | { type: \"setValue\"; path: string; value: unknown }\n | { type: \"setFieldValue\"; path: string; value: unknown, errors?: string[] }\n | { type: \"setError\"; path: string; value?: string }\n | { type: \"reset\"; }\n | { type: \"setErrors\"; errors?: object };\n\n\nfunction reducer(state: State, action: Action): State {\n const newData = {...state};\n switch (action.type) {\n case 'setValue':\n newData.formData = updateNestedValue(newData.formData, action.path, action.value);\n break;\n case 'setFieldValue':\n newData.formData = updateNestedValue(newData.formData, action.path, action.value);\n newData.errors = updateNestedValue(newData.errors, action.path, action?.errors?.length ? action.errors : null);\n break;\n case 'setError':\n newData.errors = updateNestedValue(newData.errors, action.path, action.value);\n break;\n case 'reset':\n newData.formData = {};\n newData.errors = {};\n break;\n case 'setErrors':\n newData.errors = {...action.errors};\n break;\n }\n return newData;\n}\n\nconst {\n Provider,\n useStore: useFormStore,\n useDispatch: useFormDispatch,\n useStoreInstance: useFormStoreInstance,\n} = createStoreContext(reducer, { formData: {}, errors: {} });\n\nconst FormStoreProvider: React.FC<{ children: ReactNode; formData?: FormData }> = ({children, formData}) =>\n (<Provider initialState={{ formData: formData ?? {}, errors: {} }}>{children}</Provider>);\n\n\nexport { FormStoreProvider, useFormStore, useFormDispatch, useFormStoreInstance };\n","import type {IUserRule} from \"@/plugins/validation/types\";\nimport {getNestedValue} from \"@/shared/utils\";\n\nexport const confirm: IUserRule = {\n code: 'confirm',\n fn: (value, data, args) => {\n const attr = args[0] ?? false;\n return attr ? value == getNestedValue(data, attr) : false;\n },\n message: 'Поле не совпадает с ::attr(1)'\n};\n","import type {IUserRule} from \"@/plugins/validation/types\";\n\nexport const required: IUserRule = {\n code: 'required',\n fn: (value) => {\n return value !== undefined && value !== null && value.length > 0;\n },\n message: 'Поле обязательно для заполнения'\n};\n","import type {IUserRule} from \"@/plugins/validation/types\";\n\nconst emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/;\nexport const email: IUserRule = {\n code: 'email',\n fn: (value) => {\n return emailRegex.test(value);\n },\n message: 'Поле не является email'\n};\n","import { confirm } from \"@/plugins/validation/rules/confirm\";\nimport { required } from \"@/plugins/validation/rules/required\";\nimport {email} from \"@/plugins/validation/rules/email\";\n\nexport default [confirm, required, email]\n","import type {FormData} from \"@/shared/types/common\";\nimport base from './rules';\nimport type {IUserRule} from \"@/plugins/validation/types\";\nimport {getNestedValue} from \"@/shared/utils\";\n\nexport class Validation {\n private readonly registry: IUserRule[] = [];\n private registerFields: Record<string, string[]> = {};\n constructor(public readonly onSubmit: boolean, rules: IUserRule[] = []) {\n this.registry = [...rules, ...base];\n }\n \n \n private validateRule(rule: string, data: unknown, formData: FormData): string|null {\n const [code, rawArgs] = rule.split(':');\n const args = rawArgs ? rawArgs.split(',') : [];\n const userRule = this.registry.find(i => i.code == code);\n if (!userRule) {\n return null;\n }\n const validateStatus = userRule.fn(data, formData, args);\n return !validateStatus ? this.replaceMessageArgs(userRule.message, args) : null;\n }\n \n private replaceMessageArgs(message: string, args: string[] = []): string {\n const replaceArgs = args.reduce<Record<string, string>>((acc, arg, index) => {\n acc[`::attr(${index})`] = arg;\n return acc;\n }, {});\n\n return message.replace(/::attr\\(\\d\\)/g, i => replaceArgs[i]);\n }\n \n public registerField(path: string, validators: string[]): void {\n this.registerFields[path] = validators;\n }\n\n private _validate(rules: string[], data: unknown, formData: FormData): string[] {\n return rules.map((rule) => {\n return this.validateRule(rule, data, formData);\n }).filter(i => i !== null)\n }\n validate(rules: string[], data: unknown, formData: FormData): string[] {\n return !this.onSubmit ? this._validate(rules, data, formData) : [];\n }\n \n public validateAll(formData: FormData): Record<string, string[]> {\n return Object.entries(this.registerFields).reduce<Record<string, string[]>>((acc, [path, rules]) => {\n const value = getNestedValue(formData, path);\n const validationMessage = this._validate(rules, value, formData);\n if (validationMessage.length) {\n acc[path] = validationMessage;\n }\n return acc;\n } , {});\n }\n}\n","import React, {createContext, useContext, useMemo} from \"react\";\nimport type {IUserRule} from \"@/plugins/validation/types\";\nimport {Validation} from \"@/plugins/validation/validation\";\nimport type {FormData, FormFieldConfig} from \"@/shared/types/common\";\n\nexport type TValidator = {\n rules?: IUserRule[],\n onSubmit?: boolean,\n}\n\nexport function createValidationProvider() {\n const Context = createContext<Validation | null>(null);\n const Provider: React.FC<{\n children: React.ReactNode,\n validator?: TValidator,\n }> = ({\n validator = {\n onSubmit: false,\n rules: []\n },\n children\n }) => {\n const core = useMemo(() => new Validation(validator.onSubmit ?? false, validator.rules ?? []), [validator]);\n \n return (\n <Context.Provider value={core}>\n {children}\n </Context.Provider>\n );\n }\n \n const useValidate = (rules ?: string[]) => {\n const core = useContext(Context);\n if (!core) {\n throw new Error(\"ValidationProvider missing\");\n }\n return (data: unknown, formData: FormData) => {\n return core.validate(rules ?? [], data, formData);\n }\n }\n \n const useRegister = (currentFieldPath: string, field: FormFieldConfig) => {\n const core = useContext(Context);\n if (!core) {\n throw new Error(\"ValidationProvider missing\");\n }\n \n core.registerField(currentFieldPath, field.validation ?? []);\n\n return useValidate(field.validation);\n }\n \n const useSubmitValidation = () => {\n const core = useContext(Context);\n if (!core) {\n throw new Error(\"ValidationProvider missing\");\n }\n \n return (formData: FormData) => core.validateAll(formData);\n }\n \n return {\n Provider,\n useRegister,\n useSubmitValidation,\n }\n}\n","import {createValidationProvider } from \"./provider\";\nexport { type TValidator } from \"./provider\";\n\nexport const {\n Provider: ValidationProvider,\n useRegister,\n useSubmitValidation\n} = createValidationProvider();\n","import {useFormStore, useFormDispatch, useFormStoreInstance} from \"@/shared/model/store\";\nimport {getNestedValue} from \"@/shared/utils\";\n\nimport type { FormFieldConfig, FormElementComponent} from \"@/shared/types/common\";\nimport {useRegister} from \"@/plugins/validation\";\n\ntype BuilderElementProps = {\n element: FormElementComponent;\n field: FormFieldConfig;\n path: string;\n};\n\n\nexport const DynamicBuilderElement = (props: BuilderElementProps) => {\n const Element = props.element;\n const field = props.field;\n const currentFieldPath = props.path ? `${props.path}.${field.name}` : field.name;\n const value = useFormStore((s=> getNestedValue(s.formData, currentFieldPath)));\n const errors = useFormStore((s=> s.errors[currentFieldPath]));\n const dispatch= useFormDispatch();\n const store = useFormStoreInstance();\n const validator = useRegister(currentFieldPath, field);\n return <Element\n field={{...field}}\n path={currentFieldPath}\n value={value}\n errors={errors}\n onChange={(value: any) => {\n const data = store.getState().formData;\n const errors = validator(value, data);\n dispatch({\n type: 'setFieldValue',\n path: currentFieldPath,\n value,\n errors\n });\n }}\n />;\n}\n","import React, {createContext, type ReactNode, useCallback, useContext} from \"react\";\nimport {DynamicBuilder} from \"@/entity/dynamicBuilder\";\nimport type {FormElementRegistry} from \"~/src\";\n\nexport type TFnBuilder = (layout: any, path: string | undefined, children?: ReactNode) => ReactNode;\nexport function createBuilderContext() {\n const BuilderContext = createContext<{\n builder: TFnBuilder,\n fields: FormElementRegistry,\n } | null>(null);\n \n const Provider: React.FC<{ children: React.ReactNode, fields: FormElementRegistry }> = ({\n fields,\n children\n }) => {\n const builder = useCallback<TFnBuilder>((layout, path, children) => {\n return <DynamicBuilder layout={layout} path={path}>{children}</DynamicBuilder>\n }, [fields]);\n \n return (\n <BuilderContext.Provider value={{builder, fields}}>\n {children}\n </BuilderContext.Provider>\n );\n };\n \n function useBuilder(): TFnBuilder {\n const store = useContext(BuilderContext);\n \n if (!store) {\n throw new Error(\"StoreProvider missing\");\n }\n \n return store.builder\n }\n \n function useFields(): FormElementRegistry {\n const store = useContext(BuilderContext);\n \n if (!store) {\n throw new Error(\"StoreProvider missing\");\n }\n \n return store.fields\n }\n \n return {\n Provider,\n useBuilder,\n useFields,\n };\n}\n","import { createBuilderContext } from \"./createBuilderContext\";\n\nexport const {\n Provider: BuilderProvider,\n useBuilder,\n useFields,\n} = createBuilderContext();\n","import type {TDynamicBuilder} from \"@/shared/types/common\";\nimport {DynamicBuilderElement} from \"./element\";\nimport { useFields } from \"@/entity/dynamicBuilder/model\";\n\nexport const DynamicBuilder: TDynamicBuilder = (props) => {\n const path = props.path ?? '';\n const fields = useFields();\n\n return props.layout.map((field, index) => {\n const FormElement = fields[field.type];\n \n if (!FormElement) {\n console.warn(`Неизвестный тип поля: ${field.type}. Проверьте formRegistry.`);\n return null;\n }\n\n return <DynamicBuilderElement key={`${field.name}-${index}`} element={FormElement} path={path} field={field}/>\n })\n}\n\nexport * from './model';\n","'use client';\n\nimport {DynamicBuilder, BuilderProvider} from \"@/entity/dynamicBuilder\";\nimport {forwardRef, useCallback, useEffect, useImperativeHandle, useRef} from \"react\";\nimport {useFormDispatch, useFormStoreInstance} from \"@/shared/model/store\";\nimport type {FormBuilderRef, TFormBuilder} from \"@/shared/types/common\";\nimport { useSubmitValidation } from \"@/plugins/validation\";\n\nexport const Form = forwardRef<FormBuilderRef, TFormBuilder>((props, ref) => {\n const dispatch = useFormDispatch();\n const store = useFormStoreInstance();\n const changeRef = useRef(props.onChange);\n \n useEffect(() => {\n return store.subscribeSelector(\n (s) => s.formData,\n (formData) => changeRef.current?.(formData)\n );\n }, [store]);\n \n const validation = useSubmitValidation();\n \n const submitHdl = useCallback(() => {\n if (props.onSubmit) {\n const errors = validation(store.getState().formData);\n if (Object.keys(errors).length == 0) {\n props.onSubmit(store.getState().formData);\n } else {\n dispatch({type: 'setErrors', errors })\n }\n }\n }, [props.onSubmit, validation]);\n \n useImperativeHandle(ref, () => ({\n reset: () => dispatch({type: 'reset'}),\n submit: () => submitHdl(),\n errors: () => store.getState().errors,\n }), [submitHdl, dispatch, store]);\n \n return (\n <form onSubmit={(e) => {\n e.preventDefault();\n submitHdl();\n }}\n className={props?.className}\n >\n <BuilderProvider fields={props.fields}>\n <DynamicBuilder layout={props.layout}/>\n </BuilderProvider>\n <input type=\"submit\" style={{display: 'none'}}/>\n {props.children}\n </form>\n );\n});\n","import type {FormBuilderRef, TFormBuilder} from \"../shared/types/common\";\nimport {forwardRef} from \"react\";\nimport {FormStoreProvider} from \"@/shared/model/store\";\n\nimport { Form } from \"@/widgets/form/form\";\nimport {ValidationProvider} from \"@/plugins/validation\";\n\nexport const FormBuilder = forwardRef<FormBuilderRef, TFormBuilder>((props, ref) => {\n const {formData, ...innerProps} = props;\n\n return <FormStoreProvider formData={formData}>\n <ValidationProvider validator={props.validator}>\n <Form {...innerProps} ref={ref}></Form>\n </ValidationProvider>\n </FormStoreProvider>\n});\n\nexport default FormBuilder;\n","import type { FormElementProps, FormFieldConfig, FormFieldBase, RC } from '../../../../shared/types/common';\nimport { useId } from \"react\";\n\nexport type TextFieldConfig = FormFieldBase & { type: 'text' | 'email' | 'password'; placeholder?: string; };\n\nfunction isTextFieldConfig(field: FormFieldConfig): field is TextFieldConfig {\n return field.type === 'text' || field.type === 'email' || field.type === 'password';\n}\n\nexport const TextField: RC<FormElementProps> = ({ field, value, errors, onChange }) => {\n if (!isTextFieldConfig(field)) {\n console.warn(`TextField received an invalid field config for type: ${field.type}`);\n return null;\n }\n const id = useId();\n return (\n <div style={{ marginBottom: '15px' }}>\n <label htmlFor={id}>{field.label}:</label>\n <input\n type={field.type}\n id={id}\n name={field.name}\n placeholder={field.placeholder}\n value={value || ''}\n onChange={(e) => onChange(e.target.value)}\n style={{ borderColor: errors ? 'red' : '#ccc' }}\n />\n {errors && <p style={{ color: 'red', fontSize: '0.8em' }}>{Object.values(errors).join(', ')}</p>}\n </div>\n );\n};\n","import type {FormElementProps, FormFieldBase, FormFieldConfig, RC} from \"../../../../shared/types/common.ts\";\nimport clsx from \"clsx\";\nimport {useBuilder} from \"@/entity/dynamicBuilder\";\nexport type FormGroupConfig = FormFieldBase & { variant?: 'row' | 'col', fields: FormFieldConfig[] };\n\nfunction isGroupConfig(field: FormFieldConfig): field is FormGroupConfig {\n return Array.isArray(field.fields);\n}\n\n\nexport const FormGroup: RC<FormElementProps<FormGroupConfig>> = ({field, path}) => {\n if (!isGroupConfig(field)) {\n return null;\n }\n const Builder = useBuilder()(field.fields, path);\n const variant = field.variant ?? 'col';\n \n const className = variant == 'col' ? 'flex-col' : 'flex-row';\n\n return <div>\n <div>{field.label}</div>\n <div className={clsx(className, 'flex')}>\n {Builder}\n </div>\n </div>;\n};\n","import { z } from 'zod';\n\nconst fieldShema = z.object({\n name: z.string(),\n label: z.string().optional(),\n type: z.string(),\n});\n\ntype TField = z.infer<typeof fieldShema>;\n\nexport type { TField };\nexport { fieldShema };\n"],"mappings":"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"}