@formality-ui/react 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -606,13 +606,14 @@ plain `<input>` use `ref={forwardRef}`. For **MUI v9** components (e.g.
606
606
  slotProps={{ input: { ref: forwardRef } }}
607
607
  ```
608
608
 
609
- **Runtime caveat (important).** Today `Field` delivers the RHF ref via the
610
- React-special `ref` key, **not** a top-level `forwardRef` prop. To receive it
611
- as `forwardRef` on a bare function component, either wrap your component with
612
- `React.forwardRef`, or target React 19's ref-as-prop. Making `Field` deliver a
613
- top-level `forwardRef` key for bare components is a future runtime task; the
614
- type ships the **intended contract now** so consumers can stop hand-rolling
615
- `WithFormality`.
609
+ **Runtime delivery (important).** `<Field>` delivers the RHF ref as a regular,
610
+ top-level `forwardRef` prop no `React.forwardRef` wrap is required for a
611
+ plain function component that destructures `forwardRef` and wires it to the
612
+ inner input (`ref={forwardRef}`). Consumers migrating off the old
613
+ React-special `ref` key: a `React.forwardRef`-wrapped component should consume
614
+ `props.forwardRef` (PRD §20.4), and under React 19 ref-as-prop use `forwardRef`
615
+ directly. The type ships the **intended contract** so consumers can stop
616
+ hand-rolling `WithFormality`.
616
617
 
617
618
  ## Utilities
618
619
 
package/dist/index.cjs CHANGED
@@ -562,11 +562,18 @@ function useInferredInputs(options) {
562
562
  selectProps,
563
563
  formDefaultFieldProps,
564
564
  providerDefaultFieldProps,
565
- conditions = [],
566
- subscribesTo = []
565
+ conditions,
566
+ subscribesTo
567
567
  } = options;
568
+ const signature = JSON.stringify({
569
+ selectProps,
570
+ formDefaultFieldProps,
571
+ providerDefaultFieldProps,
572
+ conditions,
573
+ subscribesTo
574
+ });
568
575
  return react.useMemo(() => {
569
- const inferred = [...subscribesTo];
576
+ const inferred = [...subscribesTo ?? []];
570
577
  if (providerDefaultFieldProps) {
571
578
  inferred.push(...core.inferFieldsFromDescriptor(providerDefaultFieldProps));
572
579
  }
@@ -576,17 +583,11 @@ function useInferredInputs(options) {
576
583
  if (selectProps) {
577
584
  inferred.push(...core.inferFieldsFromDescriptor(selectProps));
578
585
  }
579
- if (conditions.length > 0) {
586
+ if (conditions && conditions.length > 0) {
580
587
  inferred.push(...core.inferFieldsFromConditions(conditions));
581
588
  }
582
589
  return [...new Set(inferred)];
583
- }, [
584
- providerDefaultFieldProps,
585
- formDefaultFieldProps,
586
- selectProps,
587
- conditions,
588
- subscribesTo
589
- ]);
590
+ }, [signature]);
590
591
  }
591
592
 
592
593
  // src/hooks/useConditions.ts
@@ -1117,21 +1118,33 @@ function Field({
1117
1118
  [inputConfig.inputFieldProp ?? "value"]: formattedValue,
1118
1119
  onChange: handleChange(field.onChange),
1119
1120
  onBlur: field.onBlur,
1120
- ref: field.ref
1121
+ forwardRef: field.ref
1121
1122
  }
1122
1123
  });
1123
1124
  const Component = inputConfig.component;
1125
+ const isHostComponent = typeof inputConfig.component === "string";
1124
1126
  const template = inputConfig.template ?? providerConfig.inputTemplates[type] ?? providerConfig.defaultInputTemplate;
1125
1127
  const TemplateComponent = template;
1126
- const renderedField = TemplateComponent ? /* @__PURE__ */ jsxRuntime.jsx(
1127
- TemplateComponent,
1128
- {
1129
- Field: Component,
1130
- fieldProps: finalProps,
1131
- fieldState,
1132
- formState
1133
- }
1134
- ) : /* @__PURE__ */ jsxRuntime.jsx(Component, { ...finalProps });
1128
+ let renderedField;
1129
+ if (TemplateComponent) {
1130
+ renderedField = /* @__PURE__ */ jsxRuntime.jsx(
1131
+ TemplateComponent,
1132
+ {
1133
+ Field: Component,
1134
+ fieldProps: finalProps,
1135
+ fieldState,
1136
+ formState
1137
+ }
1138
+ );
1139
+ } else if (isHostComponent) {
1140
+ const { forwardRef: hostRef, ...restHostProps } = finalProps;
1141
+ renderedField = react.createElement(inputConfig.component, {
1142
+ ...restHostProps,
1143
+ ref: hostRef
1144
+ });
1145
+ } else {
1146
+ renderedField = /* @__PURE__ */ jsxRuntime.jsx(Component, { ...finalProps });
1147
+ }
1135
1148
  if (typeof children === "function") {
1136
1149
  const result = children({
1137
1150
  fieldState,