@strictly/react-form 0.0.31 → 0.0.33

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.js CHANGED
@@ -312,6 +312,7 @@ import {
312
312
  UnreachableError as UnreachableError2
313
313
  } from "@strictly/base";
314
314
  import {
315
+ copy,
315
316
  equals,
316
317
  flattenAccessorsOfType,
317
318
  flattenTypesOfType,
@@ -322,6 +323,7 @@ import {
322
323
  valuePathToTypePath
323
324
  } from "@strictly/define";
324
325
  import {
326
+ action,
325
327
  computed,
326
328
  observable,
327
329
  runInAction
@@ -332,8 +334,8 @@ var Validation = /* @__PURE__ */ ((Validation2) => {
332
334
  Validation2[Validation2["Always"] = 2] = "Always";
333
335
  return Validation2;
334
336
  })(Validation || {});
335
- var _valueChanged_dec, _dirty_dec, _accessors_dec, _knownFields_dec, _fields_dec, _validation_dec, _errorOverrides_dec, _fieldOverrides_dec, _value_dec, _init, _value, _fieldOverrides, _errorOverrides, _validation;
336
- _value_dec = [observable.ref], _fieldOverrides_dec = [observable.shallow], _errorOverrides_dec = [observable.shallow], _validation_dec = [observable.shallow], _fields_dec = [computed], _knownFields_dec = [computed], _accessors_dec = [computed], _dirty_dec = [computed], _valueChanged_dec = [computed];
337
+ var _validateAll_dec, _validateField_dec, _setFieldValue_dec, _valueChanged_dec, _dirty_dec, _accessors_dec, _knownFields_dec, _fields_dec, _value_dec, _validation_dec, _errorOverrides_dec, _fieldOverrides_dec, _observableValue_dec, _init, _observableValue, _fieldOverrides, _errorOverrides, _validation;
338
+ _observableValue_dec = [observable.ref], _fieldOverrides_dec = [observable.shallow], _errorOverrides_dec = [observable.shallow], _validation_dec = [observable.shallow], _value_dec = [computed], _fields_dec = [computed], _knownFields_dec = [computed], _accessors_dec = [computed], _dirty_dec = [computed], _valueChanged_dec = [computed], _setFieldValue_dec = [action], _validateField_dec = [action], _validateAll_dec = [action];
337
339
  var FormModel = class {
338
340
  constructor(type, originalValue, adapters, mode) {
339
341
  this.type = type;
@@ -341,7 +343,7 @@ var FormModel = class {
341
343
  this.adapters = adapters;
342
344
  this.mode = mode;
343
345
  __runInitializers(_init, 5, this);
344
- __privateAdd(this, _value, __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);
346
+ __privateAdd(this, _observableValue, __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);
345
347
  __privateAdd(this, _fieldOverrides, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);
346
348
  __privateAdd(this, _errorOverrides, __runInitializers(_init, 16, this, {})), __runInitializers(_init, 19, this);
347
349
  __privateAdd(this, _validation, __runInitializers(_init, 20, this, {})), __runInitializers(_init, 23, this);
@@ -352,11 +354,11 @@ var FormModel = class {
352
354
  // maintains the value paths of lists when the original order is destroyed by deletes or reordering
353
355
  __publicField(this, "listIndicesToKeys", {});
354
356
  this.originalValues = flattenValuesOfType(type, originalValue, this.listIndicesToKeys);
355
- this.value = mobxCopy(type, originalValue);
357
+ this.observableValue = mobxCopy(type, originalValue);
356
358
  this.flattenedTypeDefs = flattenTypesOfType(type);
357
359
  const conversions = flattenValueTo(
358
360
  type,
359
- this.value,
361
+ originalValue,
360
362
  () => {
361
363
  },
362
364
  (_t, fieldValue, _setter, typePath, valuePath) => {
@@ -390,6 +392,9 @@ var FormModel = class {
390
392
  throw new UnreachableError2(this.mode);
391
393
  }
392
394
  }
395
+ get value() {
396
+ return copy(this.type, this.observableValue);
397
+ }
393
398
  get fields() {
394
399
  return new Proxy(
395
400
  this.knownFields,
@@ -409,7 +414,7 @@ var FormModel = class {
409
414
  get knownFields() {
410
415
  return flattenValueTo(
411
416
  this.type,
412
- this.value,
417
+ this.observableValue,
413
418
  () => {
414
419
  },
415
420
  // TODO swap these to valuePath, typePath in flatten
@@ -451,7 +456,7 @@ var FormModel = class {
451
456
  const fieldOverride = this.fieldOverrides[valuePath];
452
457
  const accessor = this.getAccessorForValuePath(valuePath);
453
458
  const fieldTypeDef = this.flattenedTypeDefs[typePath];
454
- const context = this.toContext(this.value, valuePath);
459
+ const context = this.toContext(this.observableValue, valuePath);
455
460
  const defaultValue = create(valuePath, context);
456
461
  const {
457
462
  value,
@@ -543,9 +548,9 @@ var FormModel = class {
543
548
  get accessors() {
544
549
  return flattenAccessorsOfType(
545
550
  this.type,
546
- this.value,
551
+ this.observableValue,
547
552
  (value) => {
548
- this.value = mobxCopy(this.type, value);
553
+ this.observableValue = mobxCopy(this.type, value);
549
554
  },
550
555
  this.listIndicesToKeys
551
556
  );
@@ -567,7 +572,7 @@ var FormModel = class {
567
572
  });
568
573
  }
569
574
  get valueChanged() {
570
- return !equals(this.type, this.value, this.originalValue);
575
+ return !equals(this.type, this.observableValue, this.originalValue);
571
576
  }
572
577
  typePath(valuePath) {
573
578
  return valuePathToTypePath(this.type, valuePath, true);
@@ -592,7 +597,7 @@ var FormModel = class {
592
597
  elementTypePath,
593
598
  // TODO what can we use for the value path here?
594
599
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
595
- this.toContext(this.value, valuePath)
600
+ this.toContext(this.observableValue, valuePath)
596
601
  );
597
602
  const originalList = accessor.value;
598
603
  const newList = [
@@ -647,7 +652,7 @@ var FormModel = class {
647
652
  internalSetFieldValue(valuePath, value, validation) {
648
653
  const { revert } = this.getAdapterForValuePath(valuePath);
649
654
  assertExists(revert, "setting value not supported {}", valuePath);
650
- const conversion = revert(value, valuePath, this.toContext(this.value, valuePath));
655
+ const conversion = revert(value, valuePath, this.toContext(this.observableValue, valuePath));
651
656
  const accessor = this.getAccessorForValuePath(valuePath);
652
657
  return runInAction(() => {
653
658
  this.fieldOverrides[valuePath] = [value];
@@ -702,7 +707,7 @@ var FormModel = class {
702
707
  convert,
703
708
  create
704
709
  } = adapter2;
705
- const context = this.toContext(this.value, valuePath);
710
+ const context = this.toContext(this.observableValue, valuePath);
706
711
  const value = create(valuePath, context);
707
712
  const {
708
713
  value: displayValue
@@ -719,11 +724,11 @@ var FormModel = class {
719
724
  this.validation = {};
720
725
  this.fieldOverrides = {};
721
726
  this.errorOverrides = {};
722
- this.value = mobxCopy(this.type, value);
727
+ this.observableValue = mobxCopy(this.type, value);
723
728
  });
724
729
  }
725
730
  isValuePathActive(valuePath) {
726
- const values = flattenValuesOfType(this.type, this.value, this.listIndicesToKeys);
731
+ const values = flattenValuesOfType(this.type, this.observableValue, this.listIndicesToKeys);
727
732
  const keys = new Set(Object.keys(values));
728
733
  return keys.has(valuePath);
729
734
  }
@@ -766,18 +771,14 @@ var FormModel = class {
766
771
  return displayedValue !== originalDisplayedValue;
767
772
  }
768
773
  validateField(valuePath, validation = 2 /* Always */) {
769
- runInAction(() => {
770
- this.validation[valuePath] = validation;
771
- delete this.errorOverrides[valuePath];
772
- });
774
+ this.validation[valuePath] = validation;
775
+ delete this.errorOverrides[valuePath];
773
776
  return this.fields[valuePath].error == null;
774
777
  }
775
778
  validateAll(validation = 2 /* Always */) {
776
779
  const accessors = toArray(this.accessors);
777
- runInAction(() => {
778
- accessors.forEach(([valuePath]) => {
779
- this.validation[valuePath] = validation;
780
- });
780
+ accessors.forEach(([valuePath]) => {
781
+ this.validation[valuePath] = validation;
781
782
  });
782
783
  return accessors.every(
783
784
  ([valuePath]) => {
@@ -791,32 +792,50 @@ var FormModel = class {
791
792
  }
792
793
  };
793
794
  _init = __decoratorStart(null);
794
- _value = new WeakMap();
795
+ _observableValue = new WeakMap();
795
796
  _fieldOverrides = new WeakMap();
796
797
  _errorOverrides = new WeakMap();
797
798
  _validation = new WeakMap();
798
- __decorateElement(_init, 4, "value", _value_dec, FormModel, _value);
799
+ __decorateElement(_init, 4, "observableValue", _observableValue_dec, FormModel, _observableValue);
799
800
  __decorateElement(_init, 4, "fieldOverrides", _fieldOverrides_dec, FormModel, _fieldOverrides);
800
801
  __decorateElement(_init, 4, "errorOverrides", _errorOverrides_dec, FormModel, _errorOverrides);
801
802
  __decorateElement(_init, 4, "validation", _validation_dec, FormModel, _validation);
803
+ __decorateElement(_init, 2, "value", _value_dec, FormModel);
802
804
  __decorateElement(_init, 2, "fields", _fields_dec, FormModel);
803
805
  __decorateElement(_init, 2, "knownFields", _knownFields_dec, FormModel);
804
806
  __decorateElement(_init, 2, "accessors", _accessors_dec, FormModel);
805
807
  __decorateElement(_init, 2, "dirty", _dirty_dec, FormModel);
806
808
  __decorateElement(_init, 2, "valueChanged", _valueChanged_dec, FormModel);
809
+ __decorateElement(_init, 1, "setFieldValue", _setFieldValue_dec, FormModel);
810
+ __decorateElement(_init, 1, "validateField", _validateField_dec, FormModel);
811
+ __decorateElement(_init, 1, "validateAll", _validateAll_dec, FormModel);
807
812
  __decoratorMetadata(_init, FormModel);
808
813
 
809
814
  // core/mobx/hooks.tsx
810
815
  import {
811
816
  useCallback
812
817
  } from "react";
818
+
819
+ // core/mobx/peek.ts
820
+ import { when } from "mobx";
821
+ function peek(operation) {
822
+ let result;
823
+ void when(() => {
824
+ result = operation();
825
+ return true;
826
+ });
827
+ return result;
828
+ }
829
+
830
+ // core/mobx/hooks.tsx
813
831
  function useDefaultMobxFormHooks(model, {
814
832
  onValidFieldSubmit,
815
833
  onValidFormSubmit
816
834
  } = {}) {
817
835
  const onFieldValueChange = useCallback(
818
836
  function(path, value) {
819
- const validation = Math.min(model.getValidation(path), 1 /* Changed */);
837
+ const activeValidation = peek(() => model.getValidation(path));
838
+ const validation = Math.min(activeValidation, 1 /* Changed */);
820
839
  model.setFieldValue(path, value, validation);
821
840
  },
822
841
  [model]
@@ -836,8 +855,16 @@ function useDefaultMobxFormHooks(model, {
836
855
  const onFieldBlur = useCallback(
837
856
  function(path) {
838
857
  setTimeout(function() {
839
- if (model.isValuePathActive(path) && model.isFieldDirty(path) && model.fields[path].error == null) {
840
- model.validateField(path, Math.max(1 /* Changed */, model.getValidation(path)));
858
+ const [
859
+ validate4,
860
+ activeValidation
861
+ ] = peek(() => [
862
+ model.isValuePathActive(path) && model.isFieldDirty(path) && model.fields[path].error == null,
863
+ model.getValidation(path)
864
+ ]);
865
+ if (validate4) {
866
+ const validation = Math.max(1 /* Changed */, activeValidation);
867
+ model.validateField(path, validation);
841
868
  }
842
869
  }, 100);
843
870
  },
@@ -845,8 +872,10 @@ function useDefaultMobxFormHooks(model, {
845
872
  );
846
873
  const onFormSubmit = useCallback(
847
874
  function() {
848
- if (model.validateSubmit()) {
849
- onValidFormSubmit == null ? void 0 : onValidFormSubmit(model.value);
875
+ const valid = peek(() => model.validateSubmit());
876
+ if (valid && onValidFormSubmit) {
877
+ const value = peek(() => model.value);
878
+ onValidFormSubmit(value);
850
879
  }
851
880
  },
852
881
  [
@@ -1002,7 +1031,7 @@ var IntegerToStringConverter = class {
1002
1031
 
1003
1032
  // field_converters/NullableToBooleanConverter.ts
1004
1033
  import {
1005
- copy
1034
+ copy as copy2
1006
1035
  } from "@strictly/define";
1007
1036
  var NullableToBooleanConverter = class {
1008
1037
  constructor(typeDef, prototype, nullType, defaultToNull = true) {
@@ -1021,7 +1050,7 @@ var NullableToBooleanConverter = class {
1021
1050
  }
1022
1051
  revert(from) {
1023
1052
  if (from) {
1024
- const value = copy(this.typeDef, this.prototype);
1053
+ const value = copy2(this.typeDef, this.prototype);
1025
1054
  return {
1026
1055
  type: 0 /* Success */,
1027
1056
  value
@@ -1042,7 +1071,7 @@ import {
1042
1071
  reverse
1043
1072
  } from "@strictly/base";
1044
1073
  import {
1045
- copy as copy2
1074
+ copy as copy3
1046
1075
  } from "@strictly/define";
1047
1076
  var AbstractSelectValueTypeConverter = class {
1048
1077
  constructor(typeDef, values, defaultValueKey, noSuchValueError, required) {
@@ -1061,7 +1090,7 @@ var AbstractSelectValueTypeConverter = class {
1061
1090
  value: null
1062
1091
  };
1063
1092
  }
1064
- const value = prototype == null ? prototype : copy2(this.typeDef, prototype);
1093
+ const value = prototype == null ? prototype : copy3(this.typeDef, prototype);
1065
1094
  return {
1066
1095
  type: 0 /* Success */,
1067
1096
  value
@@ -1191,7 +1220,7 @@ import {
1191
1220
  } from "react";
1192
1221
 
1193
1222
  // util/Partial.tsx
1194
- import { observer } from "mobx-react";
1223
+ import { Observer } from "mobx-react";
1195
1224
  import {
1196
1225
  forwardRef,
1197
1226
  useMemo
@@ -1277,36 +1306,36 @@ function createPartialObserverComponent(Component, curriedPropsSource, additiona
1277
1306
  );
1278
1307
  }
1279
1308
  function createUnsafePartialObserverComponent(Component, curriedPropsSource, additionalPropKeys = []) {
1280
- return observer(
1281
- forwardRef(
1282
- function(props, ref) {
1283
- const C = Component;
1284
- const [
1285
- additionalProps,
1286
- exposedProps
1287
- ] = additionalPropKeys.reduce(
1288
- function([
1309
+ return forwardRef(
1310
+ function(props, ref) {
1311
+ const C = Component;
1312
+ const [
1313
+ additionalProps,
1314
+ exposedProps
1315
+ ] = additionalPropKeys.reduce(
1316
+ function([
1317
+ additionalProps2,
1318
+ exposedProps2
1319
+ ], key) {
1320
+ const value = props[
1321
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1322
+ key
1323
+ ];
1324
+ delete exposedProps2[key];
1325
+ additionalProps2[key] = value;
1326
+ return [
1289
1327
  additionalProps2,
1290
1328
  exposedProps2
1291
- ], key) {
1292
- const value = props[
1293
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1294
- key
1295
- ];
1296
- delete exposedProps2[key];
1297
- additionalProps2[key] = value;
1298
- return [
1299
- additionalProps2,
1300
- exposedProps2
1301
- ];
1302
- },
1303
- [
1304
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1305
- {},
1306
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1307
- __spreadValues({}, props)
1308
- ]
1309
- );
1329
+ ];
1330
+ },
1331
+ [
1332
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1333
+ {},
1334
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1335
+ __spreadValues({}, props)
1336
+ ]
1337
+ );
1338
+ return /* @__PURE__ */ jsx(Observer, { children: () => {
1310
1339
  const curriedProps = curriedPropsSource(additionalProps);
1311
1340
  return /* @__PURE__ */ jsx(
1312
1341
  C,
@@ -1314,8 +1343,8 @@ function createUnsafePartialObserverComponent(Component, curriedPropsSource, add
1314
1343
  ref
1315
1344
  }, curriedProps), exposedProps)
1316
1345
  );
1317
- }
1318
- )
1346
+ } });
1347
+ }
1319
1348
  );
1320
1349
  }
1321
1350
  function usePartialObserverComponent(curriedPropsSource, deps, Component, additionalPropKeys = []) {
@@ -1395,7 +1424,7 @@ import {
1395
1424
  jsonPathPrefix,
1396
1425
  jsonPathUnprefix
1397
1426
  } from "@strictly/define";
1398
- import { observer as observer2 } from "mobx-react";
1427
+ import { observer } from "mobx-react";
1399
1428
  import { jsx as jsx3 } from "react/jsx-runtime";
1400
1429
  function createFieldsView(valuePath, FieldsView, observableProps) {
1401
1430
  function toKey(subKey) {
@@ -1419,7 +1448,7 @@ function createFieldsView(valuePath, FieldsView, observableProps) {
1419
1448
  var _a;
1420
1449
  (_a = observableProps.onFieldSubmit) == null ? void 0 : _a.call(observableProps, toKey(subKey));
1421
1450
  }
1422
- const Component = observer2(
1451
+ const Component = observer(
1423
1452
  function(props) {
1424
1453
  const subFields = Object.entries(observableProps.fields).reduce(
1425
1454
  (acc, [
@@ -1459,7 +1488,7 @@ function createFieldsView(valuePath, FieldsView, observableProps) {
1459
1488
  }
1460
1489
 
1461
1490
  // mantine/createFieldView.tsx
1462
- import { Observer } from "mobx-react";
1491
+ import { Observer as Observer2 } from "mobx-react";
1463
1492
  import {
1464
1493
  useCallback as useCallback2
1465
1494
  } from "react";
@@ -1504,7 +1533,7 @@ function FieldView({
1504
1533
  form,
1505
1534
  valuePath
1506
1535
  ]);
1507
- return /* @__PURE__ */ jsx4(Observer, { children: () => {
1536
+ return /* @__PURE__ */ jsx4(Observer2, { children: () => {
1508
1537
  const {
1509
1538
  value,
1510
1539
  error
@@ -1533,13 +1562,13 @@ function createFieldView(valuePath) {
1533
1562
  }
1534
1563
 
1535
1564
  // mantine/createForm.tsx
1536
- import { observer as observer3 } from "mobx-react";
1565
+ import { observer as observer2 } from "mobx-react";
1537
1566
  import {
1538
1567
  useCallback as useCallback3
1539
1568
  } from "react";
1540
1569
  import { jsx as jsx5 } from "react/jsx-runtime";
1541
1570
  function createForm(valuePath, Form, observableProps) {
1542
- return observer3((props) => {
1571
+ return observer2((props) => {
1543
1572
  const { value } = observableProps.fields[valuePath];
1544
1573
  const onValueChange = useCallback3((value2) => {
1545
1574
  observableProps.onFieldValueChange(valuePath, value2);
@@ -1587,7 +1616,7 @@ function DefaultList({
1587
1616
  indexKeys[index]
1588
1617
  ];
1589
1618
  }).filter(function([
1590
- _value2,
1619
+ _value,
1591
1620
  _index,
1592
1621
  key
1593
1622
  ]) {
@@ -1959,7 +1988,7 @@ var MantineFormImpl = class {
1959
1988
  this
1960
1989
  );
1961
1990
  }
1962
- // TODO have an option to bind to a Text/(value: T) => JSX.Element for viewing form fields
1991
+ // TODO have an option to bind to a Text/(value: T) => ReactNode for viewing form fields
1963
1992
  };
1964
1993
  _init2 = __decoratorStart(null);
1965
1994
  _fields = new WeakMap();
@@ -2029,6 +2058,7 @@ export {
2029
2058
  mergeAdaptersWithValidators,
2030
2059
  mergeFieldAdaptersWithTwoWayConverter,
2031
2060
  mergeValidators,
2061
+ peek,
2032
2062
  prototypingFieldValueFactory,
2033
2063
  subFormFieldAdapters,
2034
2064
  trimmingStringAdapter,
package/index.ts CHANGED
@@ -7,6 +7,7 @@ export * from './core/mobx/FormModel'
7
7
  export * from './core/mobx/hooks'
8
8
  export * from './core/mobx/mergeFieldAdaptersWithTwoWayConverter'
9
9
  export * from './core/mobx/mergeFieldAdaptersWithValidators'
10
+ export * from './core/mobx/peek'
10
11
  export * from './core/mobx/subFormFieldAdapters'
11
12
  export * from './core/props'
12
13
  export * from './field_converters/IntegerToStringConverter'
@@ -1,5 +1,6 @@
1
1
  import { Observer } from 'mobx-react'
2
2
  import {
3
+ type ComponentProps,
3
4
  type ComponentType,
4
5
  useCallback,
5
6
  } from 'react'
@@ -19,7 +20,7 @@ export type FieldViewProps<F extends Fields, K extends keyof F> = {
19
20
  onBlur: () => void,
20
21
  onValueChange: (v: ValueTypeOfField<F[K]>) => void,
21
22
  onSubmit: () => void,
22
- }) => JSX.Element,
23
+ }) => ReturnType<NonNullable<ComponentProps<typeof Observer>['render']>>,
23
24
  }
24
25
 
25
26
  /**
package/mantine/hooks.tsx CHANGED
@@ -457,5 +457,5 @@ class MantineFormImpl<
457
457
  ) as unknown as MantineFieldComponent<FormProps<ValueTypeOfField<F[K]>>, P, never>
458
458
  }
459
459
 
460
- // TODO have an option to bind to a Text/(value: T) => JSX.Element for viewing form fields
460
+ // TODO have an option to bind to a Text/(value: T) => ReactNode for viewing form fields
461
461
  }
package/package.json CHANGED
@@ -1,10 +1,6 @@
1
1
  {
2
2
  "author": "Chris <chris.glover@gmail.com> (@madmaw)",
3
- "dependencies": {
4
- "@types/react": "^18.3.12",
5
- "@types/react-dom": "^18.3.1",
6
- "type-fest": "^4.27.0"
7
- },
3
+ "dependencies": {},
8
4
  "description": "Types and utilities for creating React forms",
9
5
  "devDependencies": {
10
6
  "@babel/plugin-proposal-decorators": "^7.25.9",
@@ -22,11 +18,14 @@
22
18
  "@strictly/support-vite": "*",
23
19
  "@testing-library/dom": "^10.4.0",
24
20
  "@testing-library/react": "^16.0.1",
21
+ "@types/react": "^18.3.12",
22
+ "@types/react-dom": "^18.3.1",
25
23
  "@vitejs/plugin-react": "^4.3.3",
26
24
  "concurrently": "^9.1.2",
27
25
  "jsdom": "^25.0.1",
28
26
  "resize-observer-polyfill": "^1.5.1",
29
27
  "storybook": "^8.4.5",
28
+ "type-fest": "^4.27.0",
30
29
  "vite": "^6.0.5",
31
30
  "vitest-matchmedia-mock": "^1.0.6"
32
31
  },
@@ -43,6 +42,8 @@
43
42
  "@mantine/hooks": "^7.0.0 || ^8.0.0",
44
43
  "@strictly/base": "*",
45
44
  "@strictly/define": "*",
45
+ "@types/react": "^19.0.0 || ^18.0.0",
46
+ "@types/react-dom": "^19.0.0 || ^18.0.0",
46
47
  "mobx": "^6.0.0",
47
48
  "mobx-react": "^9.1.1",
48
49
  "react": "^19.0.0 || ^18.0.0",
@@ -72,7 +73,7 @@
72
73
  "test:watch": "vitest"
73
74
  },
74
75
  "type": "module",
75
- "version": "0.0.31",
76
+ "version": "0.0.33",
76
77
  "exports": {
77
78
  ".": {
78
79
  "import": {
package/util/Partial.tsx CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type FriendlyExhaustiveArrayOfUnion } from '@strictly/base'
2
- import { observer } from 'mobx-react'
2
+ import { Observer } from 'mobx-react'
3
3
  import {
4
4
  type ComponentProps,
5
5
  type ComponentType,
@@ -274,62 +274,65 @@ export function createUnsafePartialObserverComponent<
274
274
  additionalPropKeys: readonly (keyof AdditionalProps)[] = [],
275
275
  ): UnsafePartialComponent<Component, CurriedProps, AdditionalProps> {
276
276
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
277
- return observer(
278
- forwardRef(
279
- function (
280
- props: PropsWithoutRef<RemainingComponentProps<Component, CurriedProps> & AdditionalProps>,
281
- ref: ForwardedRef<typeof Component>,
282
- ) {
283
- // forward ref types are really difficult to work with
284
- // still needs a cast as `extends ComponentType<any>` != `ComponentType<any>`
285
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unnecessary-type-assertion
286
- const C = Component as ComponentType<any>
287
- // remove the additional props from the exposed props that get passed in to the component
288
- // as this generates react warnings
289
- const [
290
- additionalProps,
291
- exposedProps,
292
- ] = additionalPropKeys.reduce<[AdditionalProps, RemainingComponentProps<Component, CurriedProps>]>(
293
- function (
294
- [
295
- additionalProps,
296
- exposedProps,
297
- ],
298
- key,
299
- ) {
300
- const value = props[
301
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
302
- key as keyof PropsWithoutRef<RemainingComponentProps<Component, CurriedProps> & AdditionalProps>
303
- ]
304
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
305
- delete exposedProps[key as keyof RemainingComponentProps<Component, CurriedProps>]
306
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
307
- additionalProps[key] = value as any
308
- return [
309
- additionalProps,
310
- exposedProps,
311
- ]
312
- },
277
+ return forwardRef(
278
+ function (
279
+ props: PropsWithoutRef<RemainingComponentProps<Component, CurriedProps> & AdditionalProps>,
280
+ ref: ForwardedRef<typeof Component>,
281
+ ) {
282
+ // forward ref types are really difficult to work with
283
+ // still needs a cast as `extends ComponentType<any>` != `ComponentType<any>`
284
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unnecessary-type-assertion
285
+ const C = Component as ComponentType<any>
286
+ // remove the additional props from the exposed props that get passed in to the component
287
+ // as this generates react warnings
288
+ const [
289
+ additionalProps,
290
+ exposedProps,
291
+ ] = additionalPropKeys.reduce<[AdditionalProps, RemainingComponentProps<Component, CurriedProps>]>(
292
+ function (
313
293
  [
314
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
315
- {} as AdditionalProps,
316
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
317
- { ...props } as RemainingComponentProps<Component, CurriedProps>,
294
+ additionalProps,
295
+ exposedProps,
318
296
  ],
319
- )
320
-
321
- // TODO is there any way we can memoize this transformation?
322
- const curriedProps = curriedPropsSource(additionalProps)
297
+ key,
298
+ ) {
299
+ const value = props[
300
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
301
+ key as keyof PropsWithoutRef<RemainingComponentProps<Component, CurriedProps> & AdditionalProps>
302
+ ]
303
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
304
+ delete exposedProps[key as keyof RemainingComponentProps<Component, CurriedProps>]
305
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
306
+ additionalProps[key] = value as any
307
+ return [
308
+ additionalProps,
309
+ exposedProps,
310
+ ]
311
+ },
312
+ [
313
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
314
+ {} as AdditionalProps,
315
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
316
+ { ...props } as RemainingComponentProps<Component, CurriedProps>,
317
+ ],
318
+ )
319
+ return (
320
+ <Observer>
321
+ {() => {
322
+ // TODO is there any way we can memoize this transformation?
323
+ const curriedProps = curriedPropsSource(additionalProps)
323
324
 
324
- return (
325
- <C
326
- ref={ref}
327
- {...curriedProps}
328
- {...exposedProps}
329
- />
330
- )
331
- },
332
- ),
325
+ return (
326
+ <C
327
+ ref={ref}
328
+ {...curriedProps}
329
+ {...exposedProps}
330
+ />
331
+ )
332
+ }}
333
+ </Observer>
334
+ )
335
+ },
333
336
  ) as UnsafePartialComponent<Component, CurriedProps, AdditionalProps>
334
337
  }
335
338