@strictly/react-form 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.
package/dist/index.cjs CHANGED
@@ -89,7 +89,6 @@ __export(index_exports, {
89
89
  AbstractSelectValueTypeConverter: () => AbstractSelectValueTypeConverter,
90
90
  DefaultErrorRenderer: () => DefaultErrorRenderer,
91
91
  FormModel: () => FormModel,
92
- FormPresenter: () => FormPresenter,
93
92
  IntegerToStringConverter: () => IntegerToStringConverter,
94
93
  NullableToBooleanConverter: () => NullableToBooleanConverter,
95
94
  SelectDiscriminatedUnionConverter: () => SelectDiscriminatedUnionConverter,
@@ -352,324 +351,10 @@ function listAdapter() {
352
351
  );
353
352
  }
354
353
 
355
- // core/mobx/form_presenter.ts
354
+ // core/mobx/form_model.ts
356
355
  var import_base2 = require("@strictly/base");
357
356
  var import_define = require("@strictly/define");
358
357
  var import_mobx = require("mobx");
359
- var FormPresenter = class {
360
- constructor(type, adapters) {
361
- this.type = type;
362
- this.adapters = adapters;
363
- }
364
- maybeGetAdapterForValuePath(valuePath) {
365
- const typePath = (0, import_define.valuePathToTypePath)(this.type, valuePath, true);
366
- return this.adapters[typePath];
367
- }
368
- getAdapterForValuePath(valuePath) {
369
- return (0, import_base2.assertExistsAndReturn)(
370
- this.maybeGetAdapterForValuePath(valuePath),
371
- "expected adapter to be defined {}",
372
- valuePath
373
- );
374
- }
375
- typePath(valuePath) {
376
- return (0, import_define.valuePathToTypePath)(this.type, valuePath, true);
377
- }
378
- setFieldValueAndValidate(model, valuePath, value) {
379
- return this.internalSetFieldValue(model, valuePath, value, true);
380
- }
381
- setFieldValue(model, valuePath, value) {
382
- return this.internalSetFieldValue(model, valuePath, value, false);
383
- }
384
- addListItem(model, valuePath, elementValue = null, index) {
385
- const listValuePath = valuePath;
386
- const accessor = model.accessors[valuePath];
387
- const listTypePath = this.typePath(valuePath);
388
- const definedIndex = index != null ? index : accessor.value.length;
389
- const elementTypePath = `${listTypePath}.*`;
390
- const elementAdapter = (0, import_base2.assertExistsAndReturn)(
391
- this.adapters[elementTypePath],
392
- "no adapter specified for list {} ({})",
393
- elementTypePath,
394
- valuePath
395
- );
396
- const element = elementValue != null ? elementValue[0] : elementAdapter.create(
397
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
398
- elementTypePath,
399
- model.value
400
- );
401
- const originalList = accessor.value;
402
- const newList = [
403
- ...originalList.slice(0, definedIndex),
404
- element,
405
- ...originalList.slice(definedIndex)
406
- ];
407
- const targetPaths = Object.keys(model.fieldOverrides).filter(function(v) {
408
- return v.startsWith(`${listValuePath}.`);
409
- }).map(function(v) {
410
- const parts = v.substring(listValuePath.length + 1).split(".");
411
- const index2 = parseInt(parts[0]);
412
- return [
413
- index2,
414
- parts.slice(1)
415
- ];
416
- }).filter(function([index2]) {
417
- return index2 >= definedIndex;
418
- }).sort(function([a], [b]) {
419
- return b - a;
420
- });
421
- (0, import_mobx.runInAction)(function() {
422
- targetPaths.forEach(function([
423
- index2,
424
- postfix
425
- ]) {
426
- const fromJsonPath = [
427
- listValuePath,
428
- `${index2}`,
429
- ...postfix
430
- ].join(".");
431
- const toJsonPath = [
432
- listValuePath,
433
- `${index2 + 1}`,
434
- ...postfix
435
- ].join(".");
436
- const fieldOverride = model.fieldOverrides[fromJsonPath];
437
- delete model.fieldOverrides[fromJsonPath];
438
- model.fieldOverrides[toJsonPath] = fieldOverride;
439
- const error = model.errors[fromJsonPath];
440
- delete model.errors[fromJsonPath];
441
- model.errors[toJsonPath] = error;
442
- });
443
- accessor.set(newList);
444
- delete model.fieldOverrides[listValuePath];
445
- });
446
- }
447
- removeListItem(model, elementValuePath) {
448
- const [
449
- listValuePath,
450
- elementIndexString
451
- ] = (0, import_base2.assertExistsAndReturn)(
452
- (0, import_define.jsonPathPop)(elementValuePath),
453
- "expected a path with two or more segments {}",
454
- elementValuePath
455
- );
456
- const accessor = model.accessors[listValuePath];
457
- const elementIndex = (0, import_base2.checkValidNumber)(
458
- parseInt(elementIndexString),
459
- "unexpected index {} ({})",
460
- elementIndexString,
461
- elementValuePath
462
- );
463
- const newList = [...accessor.value];
464
- (0, import_base2.assertState)(
465
- elementIndex >= 0 && elementIndex < newList.length,
466
- "invalid index from path {} ({})",
467
- elementIndex,
468
- elementValuePath
469
- );
470
- newList.splice(elementIndex, 1);
471
- const targetPaths = Object.keys(model.fieldOverrides).filter(function(v) {
472
- return v.startsWith(`${listValuePath}.`);
473
- }).map(function(v) {
474
- const parts = v.substring(listValuePath.length + 1).split(".");
475
- const index = parseInt(parts[0]);
476
- return [
477
- index,
478
- parts.slice(1)
479
- ];
480
- }).filter(function([index]) {
481
- return index > elementIndex;
482
- }).sort(function([a], [b]) {
483
- return a - b;
484
- });
485
- (0, import_mobx.runInAction)(function() {
486
- targetPaths.forEach(function([
487
- index,
488
- postfix
489
- ]) {
490
- const fromJsonPath = [
491
- listValuePath,
492
- `${index}`,
493
- ...postfix
494
- ].join(".");
495
- const toJsonPath = [
496
- listValuePath,
497
- `${index - 1}`,
498
- ...postfix
499
- ].join(".");
500
- const fieldOverride = model.fieldOverrides[fromJsonPath];
501
- delete model.fieldOverrides[fromJsonPath];
502
- model.fieldOverrides[toJsonPath] = fieldOverride;
503
- const error = model.errors[fromJsonPath];
504
- delete model.errors[fromJsonPath];
505
- model.errors[toJsonPath] = error;
506
- });
507
- accessor.set(newList);
508
- delete model.fieldOverrides[listValuePath];
509
- });
510
- }
511
- internalSetFieldValue(model, valuePath, value, displayValidation) {
512
- const { revert } = this.getAdapterForValuePath(valuePath);
513
- (0, import_base2.assertExists)(revert, "setting value not supported {}", valuePath);
514
- const conversion = revert(value, valuePath, model.value);
515
- const accessor = model.getAccessorForValuePath(valuePath);
516
- return (0, import_mobx.runInAction)(() => {
517
- model.fieldOverrides[valuePath] = [value];
518
- switch (conversion.type) {
519
- case 1 /* Failure */:
520
- if (displayValidation) {
521
- model.errors[valuePath] = conversion.error;
522
- }
523
- if (conversion.value != null && accessor != null) {
524
- accessor.set(conversion.value[0]);
525
- }
526
- return false;
527
- case 0 /* Success */:
528
- delete model.errors[valuePath];
529
- accessor == null ? void 0 : accessor.set(conversion.value);
530
- return true;
531
- default:
532
- throw new import_base2.UnreachableError(conversion);
533
- }
534
- });
535
- }
536
- clearFieldError(model, valuePath) {
537
- const fieldOverride = model.fieldOverrides[valuePath];
538
- if (fieldOverride != null) {
539
- (0, import_mobx.runInAction)(function() {
540
- delete model.errors[valuePath];
541
- });
542
- }
543
- }
544
- clearFieldValue(model, valuePath) {
545
- const typePath = this.typePath(valuePath);
546
- const adapter2 = this.adapters[typePath];
547
- if (adapter2 == null) {
548
- return;
549
- }
550
- const {
551
- convert,
552
- create
553
- } = adapter2;
554
- const value = create(valuePath, model.value);
555
- const {
556
- value: displayValue
557
- } = convert(value, valuePath, model.value);
558
- const key = valuePath;
559
- (0, import_mobx.runInAction)(function() {
560
- model.fieldOverrides[key] = [displayValue];
561
- });
562
- }
563
- clearAll(model, value) {
564
- (0, import_mobx.runInAction)(() => {
565
- model.errors = {};
566
- model.fieldOverrides = {};
567
- model.value = (0, import_define.mobxCopy)(this.type, value);
568
- });
569
- }
570
- isValuePathActive(model, valuePath) {
571
- const values = (0, import_define.flattenValuesOfType)(this.type, model.value);
572
- const keys = new Set(Object.keys(values));
573
- return keys.has(valuePath);
574
- }
575
- validateField(model, valuePath, ignoreDefaultValue = false) {
576
- const {
577
- convert,
578
- revert,
579
- create
580
- } = this.getAdapterForValuePath(valuePath);
581
- const fieldOverride = model.fieldOverrides[valuePath];
582
- const accessor = model.getAccessorForValuePath(valuePath);
583
- const {
584
- value: storedValue
585
- } = convert(
586
- accessor != null ? accessor.value : create(valuePath, model.value),
587
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
588
- valuePath,
589
- model.value
590
- );
591
- const value = fieldOverride != null ? fieldOverride[0] : storedValue;
592
- const dirty = storedValue !== value;
593
- (0, import_base2.assertExists)(revert, "changing field directly not supported {}", valuePath);
594
- if (ignoreDefaultValue) {
595
- const {
596
- value: defaultDisplayValue
597
- } = convert(create(valuePath, model.value), valuePath, model.value);
598
- if (defaultDisplayValue === value) {
599
- return true;
600
- }
601
- }
602
- const conversion = revert(value, valuePath, model.value);
603
- return (0, import_mobx.runInAction)(function() {
604
- switch (conversion.type) {
605
- case 1 /* Failure */:
606
- model.errors[valuePath] = conversion.error;
607
- if (conversion.value != null && accessor != null && dirty) {
608
- accessor.set(conversion.value[0]);
609
- }
610
- return false;
611
- case 0 /* Success */:
612
- delete model.errors[valuePath];
613
- if (accessor != null && dirty) {
614
- accessor.set(conversion.value);
615
- }
616
- return true;
617
- default:
618
- throw new import_base2.UnreachableError(conversion);
619
- }
620
- });
621
- }
622
- validateAll(model) {
623
- const accessors = (0, import_base2.toArray)(model.accessors).toSorted(function([a], [b]) {
624
- return a.length - b.length;
625
- });
626
- return (0, import_mobx.runInAction)(() => {
627
- return accessors.reduce(
628
- (success, [
629
- valuePath,
630
- accessor
631
- ]) => {
632
- const adapterPath = valuePath;
633
- const adapter2 = this.maybeGetAdapterForValuePath(adapterPath);
634
- if (adapter2 == null) {
635
- return success;
636
- }
637
- const {
638
- convert,
639
- revert
640
- } = adapter2;
641
- if (revert == null) {
642
- return success;
643
- }
644
- const fieldOverride = model.fieldOverrides[adapterPath];
645
- const {
646
- value: storedValue
647
- } = convert(accessor.value, valuePath, model.value);
648
- const value = fieldOverride != null ? fieldOverride[0] : storedValue;
649
- const dirty = fieldOverride != null && fieldOverride[0] !== storedValue;
650
- const conversion = revert(value, valuePath, model.value);
651
- switch (conversion.type) {
652
- case 1 /* Failure */:
653
- model.errors[adapterPath] = conversion.error;
654
- if (conversion.value != null && dirty) {
655
- accessor.set(conversion.value[0]);
656
- }
657
- return false;
658
- case 0 /* Success */:
659
- if (dirty) {
660
- accessor.set(conversion.value);
661
- }
662
- delete model.errors[adapterPath];
663
- return success;
664
- default:
665
- throw new import_base2.UnreachableError(conversion);
666
- }
667
- },
668
- true
669
- );
670
- });
671
- }
672
- };
673
358
  var _accessors_dec, _knownFields_dec, _fields_dec, _errors_dec, _fieldOverrides_dec, _value_dec, _init, _value, _fieldOverrides, _errors;
674
359
  _value_dec = [import_mobx.observable.ref], _fieldOverrides_dec = [import_mobx.observable.shallow], _errors_dec = [import_mobx.observable.shallow], _fields_dec = [import_mobx.computed], _knownFields_dec = [import_mobx.computed], _accessors_dec = [import_mobx.computed];
675
360
  var FormModel = class {
@@ -801,254 +486,381 @@ var FormModel = class {
801
486
  }
802
487
  );
803
488
  }
804
- };
805
- _init = __decoratorStart(null);
806
- _value = new WeakMap();
807
- _fieldOverrides = new WeakMap();
808
- _errors = new WeakMap();
809
- __decorateElement(_init, 4, "value", _value_dec, FormModel, _value);
810
- __decorateElement(_init, 4, "fieldOverrides", _fieldOverrides_dec, FormModel, _fieldOverrides);
811
- __decorateElement(_init, 4, "errors", _errors_dec, FormModel, _errors);
812
- __decorateElement(_init, 2, "fields", _fields_dec, FormModel);
813
- __decorateElement(_init, 2, "knownFields", _knownFields_dec, FormModel);
814
- __decorateElement(_init, 2, "accessors", _accessors_dec, FormModel);
815
- __decoratorMetadata(_init, FormModel);
816
-
817
- // core/mobx/hooks.tsx
818
- var import_react2 = require("react");
819
-
820
- // util/partial.tsx
821
- var import_mobx_react = require("mobx-react");
822
- var import_react = require("react");
823
- var import_jsx_runtime = require("react/jsx-runtime");
824
- function createSimplePartialComponent(Component, curriedProps) {
825
- return (0, import_react.forwardRef)(
826
- function(exposedProps, ref) {
827
- const C = Component;
828
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
829
- C,
830
- __spreadValues(__spreadValues({
831
- ref
832
- }, curriedProps), exposedProps)
833
- );
834
- }
835
- );
836
- }
837
- function createPartialComponent(Component, curriedPropsSource, additionalPropKeys = []) {
838
- return (0, import_react.forwardRef)(
839
- function(props, ref) {
840
- const C = Component;
841
- const [
842
- additionalProps,
843
- exposedProps
844
- ] = additionalPropKeys.reduce(
845
- function([
846
- additionalProps2,
847
- exposedProps2
848
- ], key) {
849
- const value = props[
850
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
851
- key
852
- ];
853
- delete exposedProps2[key];
854
- additionalProps2[key] = value;
855
- return [
856
- additionalProps2,
857
- exposedProps2
858
- ];
859
- },
860
- [
861
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
862
- {},
863
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
864
- __spreadValues({}, props)
865
- ]
866
- );
867
- const curriedProps = curriedPropsSource(additionalProps);
868
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
869
- C,
870
- __spreadValues(__spreadValues({
871
- ref
872
- }, curriedProps), exposedProps)
873
- );
874
- }
875
- );
876
- }
877
- function usePartialComponent(curriedPropsSource, deps, Component, additionalPropKeys = []) {
878
- return (0, import_react.useMemo)(
879
- function() {
880
- return createPartialComponent(
881
- Component,
882
- curriedPropsSource,
883
- additionalPropKeys
884
- );
885
- },
886
- // eslint-disable-next-line react-hooks/exhaustive-deps
887
- [
888
- // eslint-disable-next-line react-hooks/exhaustive-deps
889
- ...deps,
890
- Component,
891
- // eslint-disable-next-line react-hooks/exhaustive-deps
892
- ...additionalPropKeys
893
- ]
894
- );
895
- }
896
- function createPartialObserverComponent(Component, curriedPropsSource, additionalPropKeys = []) {
897
- return createUnsafePartialObserverComponent(
898
- Component,
899
- curriedPropsSource,
900
- additionalPropKeys
901
- );
902
- }
903
- function createUnsafePartialObserverComponent(Component, curriedPropsSource, additionalPropKeys = []) {
904
- return (0, import_mobx_react.observer)(
905
- (0, import_react.forwardRef)(
906
- function(props, ref) {
907
- const C = Component;
489
+ maybeGetAdapterForValuePath(valuePath) {
490
+ const typePath = (0, import_define.valuePathToTypePath)(this.type, valuePath, true);
491
+ return this.adapters[typePath];
492
+ }
493
+ getAdapterForValuePath(valuePath) {
494
+ return (0, import_base2.assertExistsAndReturn)(
495
+ this.maybeGetAdapterForValuePath(valuePath),
496
+ "expected adapter to be defined {}",
497
+ valuePath
498
+ );
499
+ }
500
+ typePath(valuePath) {
501
+ return (0, import_define.valuePathToTypePath)(this.type, valuePath, true);
502
+ }
503
+ setFieldValueAndValidate(valuePath, value) {
504
+ return this.internalSetFieldValue(valuePath, value, true);
505
+ }
506
+ setFieldValue(valuePath, value) {
507
+ return this.internalSetFieldValue(valuePath, value, false);
508
+ }
509
+ addListItem(valuePath, elementValue = null, index) {
510
+ const listValuePath = valuePath;
511
+ const accessor = this.accessors[valuePath];
512
+ const listTypePath = this.typePath(valuePath);
513
+ const definedIndex = index != null ? index : accessor.value.length;
514
+ const elementTypePath = `${listTypePath}.*`;
515
+ const elementAdapter = (0, import_base2.assertExistsAndReturn)(
516
+ this.adapters[elementTypePath],
517
+ "no adapter specified for list {} ({})",
518
+ elementTypePath,
519
+ valuePath
520
+ );
521
+ const element = elementValue != null ? elementValue[0] : elementAdapter.create(
522
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
523
+ elementTypePath,
524
+ this.value
525
+ );
526
+ const originalList = accessor.value;
527
+ const newList = [
528
+ ...originalList.slice(0, definedIndex),
529
+ element,
530
+ ...originalList.slice(definedIndex)
531
+ ];
532
+ const targetPaths = Object.keys(this.fieldOverrides).filter(function(v) {
533
+ return v.startsWith(`${listValuePath}.`);
534
+ }).map(function(v) {
535
+ const parts = v.substring(listValuePath.length + 1).split(".");
536
+ const index2 = parseInt(parts[0]);
537
+ return [
538
+ index2,
539
+ parts.slice(1)
540
+ ];
541
+ }).filter(function([index2]) {
542
+ return index2 >= definedIndex;
543
+ }).sort(function([a], [b]) {
544
+ return b - a;
545
+ });
546
+ (0, import_mobx.runInAction)(() => {
547
+ targetPaths.forEach(([
548
+ index2,
549
+ postfix
550
+ ]) => {
551
+ const fromJsonPath = [
552
+ listValuePath,
553
+ `${index2}`,
554
+ ...postfix
555
+ ].join(".");
556
+ const toJsonPath = [
557
+ listValuePath,
558
+ `${index2 + 1}`,
559
+ ...postfix
560
+ ].join(".");
561
+ const fieldOverride = this.fieldOverrides[fromJsonPath];
562
+ delete this.fieldOverrides[fromJsonPath];
563
+ this.fieldOverrides[toJsonPath] = fieldOverride;
564
+ const error = this.errors[fromJsonPath];
565
+ delete this.errors[fromJsonPath];
566
+ this.errors[toJsonPath] = error;
567
+ });
568
+ accessor.set(newList);
569
+ delete this.fieldOverrides[listValuePath];
570
+ });
571
+ }
572
+ removeListItem(...elementValuePaths) {
573
+ const orderedElementValuePaths = elementValuePaths.toSorted().reverse();
574
+ (0, import_mobx.runInAction)(() => {
575
+ orderedElementValuePaths.forEach((elementValuePath) => {
908
576
  const [
909
- additionalProps,
910
- exposedProps
911
- ] = additionalPropKeys.reduce(
912
- function([
913
- additionalProps2,
914
- exposedProps2
915
- ], key) {
916
- const value = props[
917
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
918
- key
919
- ];
920
- delete exposedProps2[key];
921
- additionalProps2[key] = value;
922
- return [
923
- additionalProps2,
924
- exposedProps2
925
- ];
926
- },
927
- [
928
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
929
- {},
930
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
931
- __spreadValues({}, props)
932
- ]
577
+ listValuePath,
578
+ elementIndexString
579
+ ] = (0, import_base2.assertExistsAndReturn)(
580
+ (0, import_define.jsonPathPop)(elementValuePath),
581
+ "expected a path with two or more segments {}",
582
+ elementValuePath
933
583
  );
934
- const curriedProps = curriedPropsSource(additionalProps);
935
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
936
- C,
937
- __spreadValues(__spreadValues({
938
- ref
939
- }, curriedProps), exposedProps)
584
+ const accessor = this.accessors[listValuePath];
585
+ const elementIndex = (0, import_base2.checkValidNumber)(
586
+ parseInt(elementIndexString),
587
+ "unexpected index {} ({})",
588
+ elementIndexString,
589
+ elementValuePath
590
+ );
591
+ const newList = [...accessor.value];
592
+ (0, import_base2.assertState)(
593
+ elementIndex >= 0 && elementIndex < newList.length,
594
+ "invalid index from path {} ({})",
595
+ elementIndex,
596
+ elementValuePath
940
597
  );
598
+ newList.splice(elementIndex, 1);
599
+ const targetPaths = Object.keys(this.fieldOverrides).filter(function(v) {
600
+ return v.startsWith(`${listValuePath}.`);
601
+ }).map(function(v) {
602
+ const parts = v.substring(listValuePath.length + 1).split(".");
603
+ const index = parseInt(parts[0]);
604
+ return [
605
+ index,
606
+ parts.slice(1)
607
+ ];
608
+ }).filter(function([index]) {
609
+ return index > elementIndex;
610
+ }).sort(function([a], [b]) {
611
+ return a - b;
612
+ });
613
+ targetPaths.forEach(([
614
+ index,
615
+ postfix
616
+ ]) => {
617
+ const fromJsonPath = [
618
+ listValuePath,
619
+ `${index}`,
620
+ ...postfix
621
+ ].join(".");
622
+ const toJsonPath = [
623
+ listValuePath,
624
+ `${index - 1}`,
625
+ ...postfix
626
+ ].join(".");
627
+ const fieldOverride = this.fieldOverrides[fromJsonPath];
628
+ delete this.fieldOverrides[fromJsonPath];
629
+ this.fieldOverrides[toJsonPath] = fieldOverride;
630
+ const error = this.errors[fromJsonPath];
631
+ delete this.errors[fromJsonPath];
632
+ this.errors[toJsonPath] = error;
633
+ });
634
+ accessor.set(newList);
635
+ delete this.fieldOverrides[listValuePath];
636
+ });
637
+ });
638
+ }
639
+ internalSetFieldValue(valuePath, value, displayValidation) {
640
+ const { revert } = this.getAdapterForValuePath(valuePath);
641
+ (0, import_base2.assertExists)(revert, "setting value not supported {}", valuePath);
642
+ const conversion = revert(value, valuePath, this.value);
643
+ const accessor = this.getAccessorForValuePath(valuePath);
644
+ return (0, import_mobx.runInAction)(() => {
645
+ this.fieldOverrides[valuePath] = [value];
646
+ switch (conversion.type) {
647
+ case 1 /* Failure */:
648
+ if (displayValidation) {
649
+ this.errors[valuePath] = conversion.error;
650
+ }
651
+ if (conversion.value != null && accessor != null) {
652
+ accessor.set(conversion.value[0]);
653
+ }
654
+ return false;
655
+ case 0 /* Success */:
656
+ delete this.errors[valuePath];
657
+ accessor == null ? void 0 : accessor.set(conversion.value);
658
+ return true;
659
+ default:
660
+ throw new import_base2.UnreachableError(conversion);
661
+ }
662
+ });
663
+ }
664
+ clearFieldError(valuePath) {
665
+ const fieldOverride = this.fieldOverrides[valuePath];
666
+ if (fieldOverride != null) {
667
+ (0, import_mobx.runInAction)(() => {
668
+ delete this.errors[valuePath];
669
+ });
670
+ }
671
+ }
672
+ clearFieldValue(valuePath) {
673
+ const typePath = this.typePath(valuePath);
674
+ const adapter2 = this.adapters[typePath];
675
+ if (adapter2 == null) {
676
+ return;
677
+ }
678
+ const {
679
+ convert,
680
+ create
681
+ } = adapter2;
682
+ const value = create(valuePath, this.value);
683
+ const {
684
+ value: displayValue
685
+ } = convert(value, valuePath, this.value);
686
+ const key = valuePath;
687
+ (0, import_mobx.runInAction)(() => {
688
+ this.fieldOverrides[key] = [displayValue];
689
+ });
690
+ }
691
+ clearAll(value) {
692
+ (0, import_mobx.runInAction)(() => {
693
+ this.errors = {};
694
+ this.fieldOverrides = {};
695
+ this.value = (0, import_define.mobxCopy)(this.type, value);
696
+ });
697
+ }
698
+ isValuePathActive(valuePath) {
699
+ const values = (0, import_define.flattenValuesOfType)(this.type, this.value);
700
+ const keys = new Set(Object.keys(values));
701
+ return keys.has(valuePath);
702
+ }
703
+ validateField(valuePath, ignoreDefaultValue = false) {
704
+ const {
705
+ convert,
706
+ revert,
707
+ create
708
+ } = this.getAdapterForValuePath(valuePath);
709
+ const fieldOverride = this.fieldOverrides[valuePath];
710
+ const accessor = this.getAccessorForValuePath(valuePath);
711
+ const {
712
+ value: storedValue
713
+ } = convert(
714
+ accessor != null ? accessor.value : create(valuePath, this.value),
715
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
716
+ valuePath,
717
+ this.value
718
+ );
719
+ const value = fieldOverride != null ? fieldOverride[0] : storedValue;
720
+ const dirty = storedValue !== value;
721
+ (0, import_base2.assertExists)(revert, "changing field directly not supported {}", valuePath);
722
+ if (ignoreDefaultValue) {
723
+ const {
724
+ value: defaultDisplayValue
725
+ } = convert(create(valuePath, this.value), valuePath, this.value);
726
+ if (defaultDisplayValue === value) {
727
+ return true;
941
728
  }
942
- )
943
- );
944
- }
945
- function usePartialObserverComponent(curriedPropsSource, deps, Component, additionalPropKeys = []) {
946
- return (0, import_react.useMemo)(
947
- function() {
948
- return createPartialObserverComponent(
949
- Component,
950
- curriedPropsSource,
951
- additionalPropKeys
729
+ }
730
+ const conversion = revert(value, valuePath, this.value);
731
+ return (0, import_mobx.runInAction)(() => {
732
+ switch (conversion.type) {
733
+ case 1 /* Failure */:
734
+ this.errors[valuePath] = conversion.error;
735
+ if (conversion.value != null && accessor != null && dirty) {
736
+ accessor.set(conversion.value[0]);
737
+ }
738
+ return false;
739
+ case 0 /* Success */:
740
+ delete this.errors[valuePath];
741
+ if (accessor != null && dirty) {
742
+ accessor.set(conversion.value);
743
+ }
744
+ return true;
745
+ default:
746
+ throw new import_base2.UnreachableError(conversion);
747
+ }
748
+ });
749
+ }
750
+ validateAll() {
751
+ const accessors = (0, import_base2.toArray)(this.accessors).toSorted(function([a], [b]) {
752
+ return a.length - b.length;
753
+ });
754
+ return (0, import_mobx.runInAction)(() => {
755
+ return accessors.reduce(
756
+ (success, [
757
+ valuePath,
758
+ accessor
759
+ ]) => {
760
+ const adapterPath = valuePath;
761
+ const adapter2 = this.maybeGetAdapterForValuePath(adapterPath);
762
+ if (adapter2 == null) {
763
+ return success;
764
+ }
765
+ const {
766
+ convert,
767
+ revert
768
+ } = adapter2;
769
+ if (revert == null) {
770
+ return success;
771
+ }
772
+ const fieldOverride = this.fieldOverrides[adapterPath];
773
+ const {
774
+ value: storedValue
775
+ } = convert(accessor.value, valuePath, this.value);
776
+ const value = fieldOverride != null ? fieldOverride[0] : storedValue;
777
+ const dirty = fieldOverride != null && fieldOverride[0] !== storedValue;
778
+ const conversion = revert(value, valuePath, this.value);
779
+ switch (conversion.type) {
780
+ case 1 /* Failure */:
781
+ this.errors[adapterPath] = conversion.error;
782
+ if (conversion.value != null && dirty) {
783
+ accessor.set(conversion.value[0]);
784
+ }
785
+ return false;
786
+ case 0 /* Success */:
787
+ if (dirty) {
788
+ accessor.set(conversion.value);
789
+ }
790
+ delete this.errors[adapterPath];
791
+ return success;
792
+ default:
793
+ throw new import_base2.UnreachableError(conversion);
794
+ }
795
+ },
796
+ true
952
797
  );
953
- },
954
- // eslint-disable-next-line react-hooks/exhaustive-deps
955
- [
956
- // eslint-disable-next-line react-hooks/exhaustive-deps
957
- ...deps,
958
- Component,
959
- // eslint-disable-next-line react-hooks/exhaustive-deps
960
- ...additionalPropKeys
961
- ]
962
- );
963
- }
798
+ });
799
+ }
800
+ };
801
+ _init = __decoratorStart(null);
802
+ _value = new WeakMap();
803
+ _fieldOverrides = new WeakMap();
804
+ _errors = new WeakMap();
805
+ __decorateElement(_init, 4, "value", _value_dec, FormModel, _value);
806
+ __decorateElement(_init, 4, "fieldOverrides", _fieldOverrides_dec, FormModel, _fieldOverrides);
807
+ __decorateElement(_init, 4, "errors", _errors_dec, FormModel, _errors);
808
+ __decorateElement(_init, 2, "fields", _fields_dec, FormModel);
809
+ __decorateElement(_init, 2, "knownFields", _knownFields_dec, FormModel);
810
+ __decorateElement(_init, 2, "accessors", _accessors_dec, FormModel);
811
+ __decoratorMetadata(_init, FormModel);
964
812
 
965
813
  // core/mobx/hooks.tsx
966
- function useDefaultMobxFormHooks(presenter, value, {
814
+ var import_react = require("react");
815
+ function useDefaultMobxFormHooks(model, {
967
816
  onValidFieldSubmit,
968
- onValidFormSubmit,
969
- FormFieldsView
817
+ onValidFormSubmit
970
818
  } = {}) {
971
- const model = (0, import_react2.useMemo)(function() {
972
- return presenter.createModel(value);
973
- }, [
974
- presenter,
975
- value
976
- ]);
977
- const onFieldValueChange = (0, import_react2.useCallback)(
978
- function(path, value2) {
979
- presenter.clearFieldError(model, path);
980
- presenter.setFieldValue(model, path, value2);
819
+ const onFieldValueChange = (0, import_react.useCallback)(
820
+ function(path, value) {
821
+ model.clearFieldError(path);
822
+ model.setFieldValue(path, value);
981
823
  },
982
- [
983
- presenter,
984
- model
985
- ]
824
+ [model]
986
825
  );
987
- const onFieldSubmit = (0, import_react2.useCallback)(
826
+ const onFieldSubmit = (0, import_react.useCallback)(
988
827
  function(valuePath) {
989
- if (presenter.validateField(model, valuePath)) {
990
- onValidFieldSubmit == null ? void 0 : onValidFieldSubmit(model, valuePath);
828
+ if (model.validateField(valuePath)) {
829
+ onValidFieldSubmit == null ? void 0 : onValidFieldSubmit(valuePath);
991
830
  }
992
831
  return false;
993
832
  },
994
833
  [
995
- presenter,
996
834
  model,
997
835
  onValidFieldSubmit
998
836
  ]
999
837
  );
1000
- const onFieldBlur = (0, import_react2.useCallback)(
838
+ const onFieldBlur = (0, import_react.useCallback)(
1001
839
  function(path) {
1002
840
  setTimeout(function() {
1003
- if (presenter.isValuePathActive(model, path)) {
1004
- presenter.validateField(model, path, true);
841
+ if (model.isValuePathActive(path)) {
842
+ model.validateField(path, true);
1005
843
  }
1006
844
  }, 100);
1007
845
  },
1008
- [
1009
- presenter,
1010
- model
1011
- ]
846
+ [model]
1012
847
  );
1013
- const onFormSubmit = (0, import_react2.useCallback)(
848
+ const onFormSubmit = (0, import_react.useCallback)(
1014
849
  function() {
1015
- if (presenter.validateAll(model)) {
1016
- onValidFormSubmit == null ? void 0 : onValidFormSubmit(model, model.value);
850
+ if (model.validateAll()) {
851
+ onValidFormSubmit == null ? void 0 : onValidFormSubmit(model.value);
1017
852
  }
1018
853
  },
1019
854
  [
1020
- presenter,
1021
855
  model,
1022
856
  onValidFormSubmit
1023
857
  ]
1024
858
  );
1025
- const FormFields = (0, import_react2.useMemo)(() => {
1026
- if (FormFieldsView == null) {
1027
- return void 0;
1028
- }
1029
- return createUnsafePartialObserverComponent(FormFieldsView, () => {
1030
- return {
1031
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1032
- fields: model.fields,
1033
- onFieldBlur,
1034
- onFieldSubmit,
1035
- onFieldValueChange
1036
- };
1037
- });
1038
- }, [
1039
- model,
1040
- FormFieldsView,
1041
- onFieldBlur,
1042
- onFieldSubmit,
1043
- onFieldValueChange
1044
- ]);
1045
859
  return {
1046
- model,
1047
860
  onFieldValueChange,
1048
861
  onFieldSubmit,
1049
862
  onFieldBlur,
1050
- onFormSubmit,
1051
- FormFields
863
+ onFormSubmit
1052
864
  };
1053
865
  }
1054
866
 
@@ -1359,6 +1171,151 @@ var import_base6 = require("@strictly/base");
1359
1171
  var import_mobx2 = require("mobx");
1360
1172
  var import_react4 = require("react");
1361
1173
 
1174
+ // util/partial.tsx
1175
+ var import_mobx_react = require("mobx-react");
1176
+ var import_react2 = require("react");
1177
+ var import_jsx_runtime = require("react/jsx-runtime");
1178
+ function createSimplePartialComponent(Component, curriedProps) {
1179
+ return (0, import_react2.forwardRef)(
1180
+ function(exposedProps, ref) {
1181
+ const C = Component;
1182
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1183
+ C,
1184
+ __spreadValues(__spreadValues({
1185
+ ref
1186
+ }, curriedProps), exposedProps)
1187
+ );
1188
+ }
1189
+ );
1190
+ }
1191
+ function createPartialComponent(Component, curriedPropsSource, additionalPropKeys = []) {
1192
+ return (0, import_react2.forwardRef)(
1193
+ function(props, ref) {
1194
+ const C = Component;
1195
+ const [
1196
+ additionalProps,
1197
+ exposedProps
1198
+ ] = additionalPropKeys.reduce(
1199
+ function([
1200
+ additionalProps2,
1201
+ exposedProps2
1202
+ ], key) {
1203
+ const value = props[
1204
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1205
+ key
1206
+ ];
1207
+ delete exposedProps2[key];
1208
+ additionalProps2[key] = value;
1209
+ return [
1210
+ additionalProps2,
1211
+ exposedProps2
1212
+ ];
1213
+ },
1214
+ [
1215
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1216
+ {},
1217
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1218
+ __spreadValues({}, props)
1219
+ ]
1220
+ );
1221
+ const curriedProps = curriedPropsSource(additionalProps);
1222
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1223
+ C,
1224
+ __spreadValues(__spreadValues({
1225
+ ref
1226
+ }, curriedProps), exposedProps)
1227
+ );
1228
+ }
1229
+ );
1230
+ }
1231
+ function usePartialComponent(curriedPropsSource, deps, Component, additionalPropKeys = []) {
1232
+ return (0, import_react2.useMemo)(
1233
+ function() {
1234
+ return createPartialComponent(
1235
+ Component,
1236
+ curriedPropsSource,
1237
+ additionalPropKeys
1238
+ );
1239
+ },
1240
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1241
+ [
1242
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1243
+ ...deps,
1244
+ Component,
1245
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1246
+ ...additionalPropKeys
1247
+ ]
1248
+ );
1249
+ }
1250
+ function createPartialObserverComponent(Component, curriedPropsSource, additionalPropKeys = []) {
1251
+ return createUnsafePartialObserverComponent(
1252
+ Component,
1253
+ curriedPropsSource,
1254
+ additionalPropKeys
1255
+ );
1256
+ }
1257
+ function createUnsafePartialObserverComponent(Component, curriedPropsSource, additionalPropKeys = []) {
1258
+ return (0, import_mobx_react.observer)(
1259
+ (0, import_react2.forwardRef)(
1260
+ function(props, ref) {
1261
+ const C = Component;
1262
+ const [
1263
+ additionalProps,
1264
+ exposedProps
1265
+ ] = additionalPropKeys.reduce(
1266
+ function([
1267
+ additionalProps2,
1268
+ exposedProps2
1269
+ ], key) {
1270
+ const value = props[
1271
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1272
+ key
1273
+ ];
1274
+ delete exposedProps2[key];
1275
+ additionalProps2[key] = value;
1276
+ return [
1277
+ additionalProps2,
1278
+ exposedProps2
1279
+ ];
1280
+ },
1281
+ [
1282
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1283
+ {},
1284
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1285
+ __spreadValues({}, props)
1286
+ ]
1287
+ );
1288
+ const curriedProps = curriedPropsSource(additionalProps);
1289
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1290
+ C,
1291
+ __spreadValues(__spreadValues({
1292
+ ref
1293
+ }, curriedProps), exposedProps)
1294
+ );
1295
+ }
1296
+ )
1297
+ );
1298
+ }
1299
+ function usePartialObserverComponent(curriedPropsSource, deps, Component, additionalPropKeys = []) {
1300
+ return (0, import_react2.useMemo)(
1301
+ function() {
1302
+ return createPartialObserverComponent(
1303
+ Component,
1304
+ curriedPropsSource,
1305
+ additionalPropKeys
1306
+ );
1307
+ },
1308
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1309
+ [
1310
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1311
+ ...deps,
1312
+ Component,
1313
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1314
+ ...additionalPropKeys
1315
+ ]
1316
+ );
1317
+ }
1318
+
1362
1319
  // mantine/create_checkbox.tsx
1363
1320
  var import_jsx_runtime2 = require("react/jsx-runtime");
1364
1321
  function createCheckbox(valuePath, Checkbox) {
@@ -1412,14 +1369,15 @@ function createCheckbox(valuePath, Checkbox) {
1412
1369
  }
1413
1370
 
1414
1371
  // mantine/create_fields_view.tsx
1372
+ var import_define7 = require("@strictly/define");
1415
1373
  var import_mobx_react2 = require("mobx-react");
1416
1374
  var import_jsx_runtime3 = require("react/jsx-runtime");
1417
1375
  function createFieldsView(valuePath, FieldsView, observableProps) {
1418
1376
  function toKey(subKey) {
1419
- return subKey.replace("$", valuePath);
1377
+ return (0, import_define7.jsonPathPrefix)(valuePath, subKey);
1420
1378
  }
1421
1379
  function toSubKey(key) {
1422
- return key.replace(valuePath, "$");
1380
+ return (0, import_define7.jsonPathUnprefix)(valuePath, key);
1423
1381
  }
1424
1382
  function onFieldValueChange(subKey, value) {
1425
1383
  observableProps.onFieldValueChange(toKey(subKey), value);
@@ -1866,6 +1824,7 @@ var MantineFormImpl = class {
1866
1824
  this
1867
1825
  );
1868
1826
  }
1827
+ // TODO have an option to bind to a Text/(value: T) => JSX.Element for viewing form fields
1869
1828
  };
1870
1829
  _init2 = __decoratorStart(null);
1871
1830
  _fields = new WeakMap();
@@ -1873,7 +1832,7 @@ __decorateElement(_init2, 4, "fields", _fields_dec2, MantineFormImpl, _fields);
1873
1832
  __decoratorMetadata(_init2, MantineFormImpl);
1874
1833
 
1875
1834
  // types/merge_validators.ts
1876
- var import_define7 = require("@strictly/define");
1835
+ var import_define8 = require("@strictly/define");
1877
1836
  function mergeValidators(validators1, validators2) {
1878
1837
  const validators = __spreadValues(__spreadValues({}, validators1), validators2);
1879
1838
  const keys1 = new Set(Object.keys(validators1));
@@ -1885,16 +1844,16 @@ function mergeValidators(validators1, validators2) {
1885
1844
  validators3[key] = {
1886
1845
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1887
1846
  validate: function(value, valuePath, context) {
1888
- const error = (0, import_define7.validate)(validator1, value, valuePath, context);
1847
+ const error = (0, import_define8.validate)(validator1, value, valuePath, context);
1889
1848
  if (error != null) {
1890
1849
  return error;
1891
1850
  }
1892
- return (0, import_define7.validate)(validator2, value, valuePath, context);
1851
+ return (0, import_define8.validate)(validator2, value, valuePath, context);
1893
1852
  },
1894
1853
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1895
1854
  annotations: function(valuePath, context) {
1896
- const annotations1 = (0, import_define7.annotations)(validator1, valuePath, context);
1897
- const annotations22 = (0, import_define7.annotations)(validator2, valuePath, context);
1855
+ const annotations1 = (0, import_define8.annotations)(validator1, valuePath, context);
1856
+ const annotations22 = (0, import_define8.annotations)(validator2, valuePath, context);
1898
1857
  return {
1899
1858
  readonly: annotations1.readonly || annotations22.readonly,
1900
1859
  required: annotations1.required || annotations22.required
@@ -1912,7 +1871,6 @@ function mergeValidators(validators1, validators2) {
1912
1871
  AbstractSelectValueTypeConverter,
1913
1872
  DefaultErrorRenderer,
1914
1873
  FormModel,
1915
- FormPresenter,
1916
1874
  IntegerToStringConverter,
1917
1875
  NullableToBooleanConverter,
1918
1876
  SelectDiscriminatedUnionConverter,