@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 +8 -7
- package/dist/index.cjs +34 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -12
- package/dist/index.d.ts +12 -12
- package/dist/index.js +35 -22
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -202,10 +202,10 @@ declare function defineInputs<T extends Record<string, ReactInputConfig>>(inputs
|
|
|
202
202
|
* `<Field>` renders your input component via React Hook Form's `<Controller>`.
|
|
203
203
|
* At runtime Formality merges a `coreProps` bundle onto the component (name,
|
|
204
204
|
* value, onChange, onBlur, and — as a React-special key — `ref`). The three
|
|
205
|
-
* members below are the **
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
205
|
+
* members below are the **injected-props contract**: `formState` reaches
|
|
206
|
+
* templates and render-prop children; `state` (subscribed field state) and a
|
|
207
|
+
* top-level `forwardRef` key are delivered at runtime by `<Field>` (see
|
|
208
|
+
* "Runtime delivery" below).
|
|
209
209
|
*
|
|
210
210
|
* **Destructure before forwarding.** Component authors MUST destructure
|
|
211
211
|
* `state`, `formState`, and `forwardRef` OUT of props before spreading the
|
|
@@ -224,14 +224,14 @@ declare function defineInputs<T extends Record<string, ReactInputConfig>>(inputs
|
|
|
224
224
|
* For MUI v9 components that no longer accept a top-level `inputRef`, wire it
|
|
225
225
|
* via slots: `slotProps={{ input: { ref: forwardRef } }}` (PRD §5.3.8).
|
|
226
226
|
*
|
|
227
|
-
* **Runtime
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
* stop hand-rolling a lossy `WithFormality<P>`.
|
|
227
|
+
* **Runtime delivery (important).** `<Field>` delivers RHF's ref as a regular,
|
|
228
|
+
* top-level, enumerable prop named `forwardRef` — no `React.forwardRef` wrap
|
|
229
|
+
* is required for a plain function component that destructures `forwardRef`
|
|
230
|
+
* and wires it to the inner input (`ref={forwardRef}`). Consumers migrating
|
|
231
|
+
* off the old React-special `ref` key: a `React.forwardRef`-wrapped component
|
|
232
|
+
* should consume `props.forwardRef` (PRD §20.4), and under React 19
|
|
233
|
+
* ref-as-prop use `forwardRef` directly. The type ships the intended contract
|
|
234
|
+
* so consumers stop hand-rolling a lossy `WithFormality<P>`.
|
|
235
235
|
*
|
|
236
236
|
* @template P - the field component's own props (e.g. TextFieldProps). Defaults
|
|
237
237
|
* to `unknown` so existing `ComponentType<any>` casts remain valid.
|
package/dist/index.d.ts
CHANGED
|
@@ -202,10 +202,10 @@ declare function defineInputs<T extends Record<string, ReactInputConfig>>(inputs
|
|
|
202
202
|
* `<Field>` renders your input component via React Hook Form's `<Controller>`.
|
|
203
203
|
* At runtime Formality merges a `coreProps` bundle onto the component (name,
|
|
204
204
|
* value, onChange, onBlur, and — as a React-special key — `ref`). The three
|
|
205
|
-
* members below are the **
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
205
|
+
* members below are the **injected-props contract**: `formState` reaches
|
|
206
|
+
* templates and render-prop children; `state` (subscribed field state) and a
|
|
207
|
+
* top-level `forwardRef` key are delivered at runtime by `<Field>` (see
|
|
208
|
+
* "Runtime delivery" below).
|
|
209
209
|
*
|
|
210
210
|
* **Destructure before forwarding.** Component authors MUST destructure
|
|
211
211
|
* `state`, `formState`, and `forwardRef` OUT of props before spreading the
|
|
@@ -224,14 +224,14 @@ declare function defineInputs<T extends Record<string, ReactInputConfig>>(inputs
|
|
|
224
224
|
* For MUI v9 components that no longer accept a top-level `inputRef`, wire it
|
|
225
225
|
* via slots: `slotProps={{ input: { ref: forwardRef } }}` (PRD §5.3.8).
|
|
226
226
|
*
|
|
227
|
-
* **Runtime
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
* stop hand-rolling a lossy `WithFormality<P>`.
|
|
227
|
+
* **Runtime delivery (important).** `<Field>` delivers RHF's ref as a regular,
|
|
228
|
+
* top-level, enumerable prop named `forwardRef` — no `React.forwardRef` wrap
|
|
229
|
+
* is required for a plain function component that destructures `forwardRef`
|
|
230
|
+
* and wires it to the inner input (`ref={forwardRef}`). Consumers migrating
|
|
231
|
+
* off the old React-special `ref` key: a `React.forwardRef`-wrapped component
|
|
232
|
+
* should consume `props.forwardRef` (PRD §20.4), and under React 19
|
|
233
|
+
* ref-as-prop use `forwardRef` directly. The type ships the intended contract
|
|
234
|
+
* so consumers stop hand-rolling a lossy `WithFormality<P>`.
|
|
235
235
|
*
|
|
236
236
|
* @template P - the field component's own props (e.g. TextFieldProps). Defaults
|
|
237
237
|
* to `unknown` so existing `ComponentType<any>` casts remain valid.
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext, useContext, useMemo, useRef, useState, useCallback, useEffect } from 'react';
|
|
1
|
+
import { createContext, useContext, useMemo, useRef, useState, useCallback, useEffect, createElement } from 'react';
|
|
2
2
|
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
import { useForm, FormProvider, useWatch, Controller, useFormContext as useFormContext$1 } from 'react-hook-form';
|
|
4
4
|
import { debounce } from 'lodash-es';
|
|
@@ -560,11 +560,18 @@ function useInferredInputs(options) {
|
|
|
560
560
|
selectProps,
|
|
561
561
|
formDefaultFieldProps,
|
|
562
562
|
providerDefaultFieldProps,
|
|
563
|
-
conditions
|
|
564
|
-
subscribesTo
|
|
563
|
+
conditions,
|
|
564
|
+
subscribesTo
|
|
565
565
|
} = options;
|
|
566
|
+
const signature = JSON.stringify({
|
|
567
|
+
selectProps,
|
|
568
|
+
formDefaultFieldProps,
|
|
569
|
+
providerDefaultFieldProps,
|
|
570
|
+
conditions,
|
|
571
|
+
subscribesTo
|
|
572
|
+
});
|
|
566
573
|
return useMemo(() => {
|
|
567
|
-
const inferred = [...subscribesTo];
|
|
574
|
+
const inferred = [...subscribesTo ?? []];
|
|
568
575
|
if (providerDefaultFieldProps) {
|
|
569
576
|
inferred.push(...inferFieldsFromDescriptor(providerDefaultFieldProps));
|
|
570
577
|
}
|
|
@@ -574,17 +581,11 @@ function useInferredInputs(options) {
|
|
|
574
581
|
if (selectProps) {
|
|
575
582
|
inferred.push(...inferFieldsFromDescriptor(selectProps));
|
|
576
583
|
}
|
|
577
|
-
if (conditions.length > 0) {
|
|
584
|
+
if (conditions && conditions.length > 0) {
|
|
578
585
|
inferred.push(...inferFieldsFromConditions(conditions));
|
|
579
586
|
}
|
|
580
587
|
return [...new Set(inferred)];
|
|
581
|
-
}, [
|
|
582
|
-
providerDefaultFieldProps,
|
|
583
|
-
formDefaultFieldProps,
|
|
584
|
-
selectProps,
|
|
585
|
-
conditions,
|
|
586
|
-
subscribesTo
|
|
587
|
-
]);
|
|
588
|
+
}, [signature]);
|
|
588
589
|
}
|
|
589
590
|
|
|
590
591
|
// src/hooks/useConditions.ts
|
|
@@ -1115,21 +1116,33 @@ function Field({
|
|
|
1115
1116
|
[inputConfig.inputFieldProp ?? "value"]: formattedValue,
|
|
1116
1117
|
onChange: handleChange(field.onChange),
|
|
1117
1118
|
onBlur: field.onBlur,
|
|
1118
|
-
|
|
1119
|
+
forwardRef: field.ref
|
|
1119
1120
|
}
|
|
1120
1121
|
});
|
|
1121
1122
|
const Component = inputConfig.component;
|
|
1123
|
+
const isHostComponent = typeof inputConfig.component === "string";
|
|
1122
1124
|
const template = inputConfig.template ?? providerConfig.inputTemplates[type] ?? providerConfig.defaultInputTemplate;
|
|
1123
1125
|
const TemplateComponent = template;
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1126
|
+
let renderedField;
|
|
1127
|
+
if (TemplateComponent) {
|
|
1128
|
+
renderedField = /* @__PURE__ */ jsx(
|
|
1129
|
+
TemplateComponent,
|
|
1130
|
+
{
|
|
1131
|
+
Field: Component,
|
|
1132
|
+
fieldProps: finalProps,
|
|
1133
|
+
fieldState,
|
|
1134
|
+
formState
|
|
1135
|
+
}
|
|
1136
|
+
);
|
|
1137
|
+
} else if (isHostComponent) {
|
|
1138
|
+
const { forwardRef: hostRef, ...restHostProps } = finalProps;
|
|
1139
|
+
renderedField = createElement(inputConfig.component, {
|
|
1140
|
+
...restHostProps,
|
|
1141
|
+
ref: hostRef
|
|
1142
|
+
});
|
|
1143
|
+
} else {
|
|
1144
|
+
renderedField = /* @__PURE__ */ jsx(Component, { ...finalProps });
|
|
1145
|
+
}
|
|
1133
1146
|
if (typeof children === "function") {
|
|
1134
1147
|
const result = children({
|
|
1135
1148
|
fieldState,
|