Socket
Socket
Sign inDemoInstall

formula-one

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

formula-one - npm Package Compare versions

Comparing version 0.5.0 to 0.6.0

dist/feedbackStrategies.js

4

CHANGELOG.md
# Changelog
### v0.6.0
- Rework the `feedbackStrategy` prop. Several primitive strategies and algebraic combinators are exported under `FeedbackStrategies`, a new top-level export. See the documentation for more info.
### v0.5.0

@@ -4,0 +8,0 @@

42

dist/Form.js

@@ -26,2 +26,4 @@ "use strict";

require("./feedbackStrategies");
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

@@ -91,38 +93,2 @@

// FEATURE(zach): Change these to be mix-and-matchable (i.e. OnSubmit & OnChange, OnSuccess | OnTouch)
function getShouldShowError(strategy) {
switch (strategy) {
case "Always":
return function () {
return true;
};
case "OnFirstTouch":
return function (_metaForm, meta) {
return meta.touched;
};
case "OnFirstChange":
return function (_metaForm, meta) {
return meta.changed;
};
case "OnFirstSuccess":
return function (_metaForm, meta) {
return meta.succeeded;
};
case "OnFirstSuccessOrFirstTouch":
return function (_metaForm, meta) {
return meta.succeeded || meta.touched;
};
case "OnSubmit":
return function (metaForm) {
return metaForm.submitted;
};
default:
// eslint-disable-next-line no-unused-expressions
strategy;
throw new Error("Unimplemented feedback strategy: " + strategy);
}
}
var Form = function (_React$Component) {

@@ -230,3 +196,3 @@ _inherits(Form, _React$Component);

value: _extends({
shouldShowError: getShouldShowError(this.props.feedbackStrategy).bind(null, metaForm)
shouldShowError: this.props.feedbackStrategy.bind(null, metaForm)
}, metaForm)

@@ -242,3 +208,3 @@ },

changed: (0, _formState2.getExtras)(formState).meta.changed,
shouldShowErrors: getShouldShowError(this.props.feedbackStrategy)(metaForm, (0, _formState2.getExtras)(formState).meta),
shouldShowErrors: this.props.feedbackStrategy(metaForm, (0, _formState2.getExtras)(formState).meta),
unfilteredErrors: (0, _formState2.flatRootErrors)(formState),

@@ -245,0 +211,0 @@ asyncValidationInFlight: false, // no validations on Form

@@ -6,4 +6,7 @@ "use strict";

});
exports.TestUtils = exports.Field = exports.ErrorsHelper = exports.ArrayField = exports.ObjectField = exports.Form = undefined;
exports.TestUtils = exports.mergedStrategies = exports.Field = exports.ErrorsHelper = exports.ArrayField = exports.ObjectField = exports.Form = undefined;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // strict
// Just re-exports and some masssaging
var _Form = require("./Form");

@@ -54,2 +57,6 @@

var _FeedbackStrategies = require("./FeedbackStrategies");
var _FeedbackStrategies2 = _interopRequireDefault(_FeedbackStrategies);
var _TestUtils2 = require("./TestUtils");

@@ -63,2 +70,8 @@

var mergedStrategies = _extends({}, _FeedbackStrategies2.default, {
and: _FeedbackStrategies.and,
or: _FeedbackStrategies.or,
not: _FeedbackStrategies.not
});
exports.mergedStrategies = mergedStrategies;
exports.TestUtils = _TestUtils;

@@ -15,2 +15,6 @@ "use strict";

var _feedbackStrategies = require("../feedbackStrategies");
var _feedbackStrategies2 = _interopRequireDefault(_feedbackStrategies);
var _Form = require("../Form");

@@ -100,3 +104,3 @@

initialValue: 1,
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: onSubmit,

@@ -145,3 +149,3 @@ serverErrors: { "/": ["Server error", "Another server error"] }

},
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: onSubmit,

@@ -192,3 +196,3 @@ serverErrors: {

},
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: onSubmit,

@@ -221,3 +225,3 @@ serverErrors: {

},
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: onSubmit,

@@ -263,3 +267,3 @@ serverErrors: {

},
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: onSubmit,

@@ -343,3 +347,3 @@ serverErrors: null

},
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: onSubmit,

@@ -400,3 +404,3 @@ serverErrors: null

initialValue: 1,
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: onSubmit,

@@ -425,3 +429,3 @@ serverErrors: null

initialValue: 1,
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: onSubmit,

@@ -463,3 +467,3 @@ serverErrors: null

initialValue: 1,
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: onSubmit,

@@ -499,3 +503,3 @@ serverErrors: { "/": ["Server error", "Another server error"] }

initialValue: 1,
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: jest.fn(),

@@ -535,3 +539,3 @@ serverErrors: { "/": ["Server error", "Another server error"] }

initialValue: 1,
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: onSubmit,

@@ -557,3 +561,3 @@ serverErrors: { "/": ["Server error", "Another server error"] }

initialValue: 1,
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Touched,
onSubmit: jest.fn(),

@@ -594,3 +598,3 @@ serverErrors: { "/": ["Server error", "Another server error"] }

initialValue: 1,
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: onSubmit,

@@ -618,3 +622,3 @@ serverErrors: { "/": ["Server error", "Another server error"] }

initialValue: 1,
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: onSubmit,

@@ -641,3 +645,3 @@ serverErrors: { "/": ["Server error", "Another server error"] }

initialValue: 1,
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onSubmit: onSubmit,

@@ -669,3 +673,3 @@ serverErrors: { "/": ["Server error", "Another server error"] }

initialValue: 1,
feedbackStrategy: "OnFirstTouch",
feedbackStrategy: _feedbackStrategies2.default.Always,
onChange: onChange,

@@ -672,0 +676,0 @@ serverErrors: { "/": ["Server error", "Another server error"] }

{
"name": "formula-one",
"version": "0.5.0",
"version": "0.6.0",
"description": "Strongly-typed React form state management",

@@ -5,0 +5,0 @@ "author": "Zach Gotsch",

@@ -1,1 +0,392 @@

todo
# formula-one
**formula-one** is a library which makes it easier to write type-safe forms with validations and complex inputs.
## A simple example
```jsx
type Person = {
name: string,
age: string,
side: "Empire" | "Rebels",
};
const emptyPerson: Person = {
name: "",
age: null,
side: "Empire",
};
<Form
feedbackStrategy="Always"
initialValue={emptyPerson}
onSubmit={savePerson}
>
{(link, onSubmit) => (
<ObjectField link={link}>
{links => (
<>
<Field link={links.name}>
{(value, errors, onChange, onBlur) => (
<>
<label>Name:</label>
<input type="text" onChange={onChange} onBlur={onBlur} />
</>
)}
</Field>
<Field link={links.age}>
{(value, errors, onChange, onBlur) => (
<>
<label>Age:</label>
<input type="text" onChange={onChange} onBlur={onBlur} />
</>
)}
</Field>
<Field link={links.side}>
{(value, errors, onChange, onBlur) => (
<>
<label>Side:</label>
<select onChange={onChange} onBlur={onBlur} value={value}>
<option value="Empire">Empire</option>
<option value="Rebels">Rebels</option>
</select>
</>
)}
</Field>
<div>
<button onClick={onSubmit}>Submit</button>
</div>
</>
)}
</ObjectField>
)}
</Form>;
```
## Philosophy
**formula-one** helps you write forms in React by managing the state of your form and ensuring your inputs are the right type. It does this by introducing a new abstraction, called a _Field_. A _Field_ wraps some value and provides a way to render and edit that value. A simple _Field_ might wrap a `string`, which displays and edits its value through an `<input type="text">`. A more complex value, such as a date and time might be displayed as an ISO 8601 string and be edited through a calendar input.
*Field*s are specified using the `<Field>` component, which wraps your input using a render prop. It provides the value, errors, onChange, and onBlur handlers, which should be hooked up to your input.
Individual *Field*s are aggregated into objects and arrays using the `<ObjectField>` and `<ArrayField>` components. These components enable you to build forms with multiple fields.
In **formula-one**, all of the form's state is held in the `<Form>` component, and communicated to its internal *Field*s via opaque props called *link*s. These links contain all of the data and metadata used to render an input and its associated errors.
<!-- something about tree here? -->
## Validations
### Simple Validation
**formula-one** provides an api for specifying validations on *Field*s. Each _Field_ exposes a `validation` props, which has the type `T => Array<string>` for a `Field` of type `T`. Each string represents an error message, and the empty array indicates no errors.
An example of a `Field<string>` which doesn't allow empty strings:
```jsx
function noEmptyStrings(s: string): Array<string> {
if (s === "") {
return ["Cannot be empty"];
}
}
<Field link={link} validation={noEmptyStrings}>
{(value, errors, onChange, onBlur)} => (
<>
<input type="text" value={value} />
<ul class="input_errors">
{errors.map(error => (
<li>{error}</li>
))}
</ul>
</>
)}
</Field>;
```
### When to show errors
In addition to tracking errors and validating when inputs change, **formula-one** tracks metadata to help you decide whether you should show errors to your user. `<Form>` allows you to specify a strategy for when to show errors.
Some base strategies are exported as fields on the `FeedbackStrategies` object. Here is a table of the strategies and their behavior.
| Strategy identifier | Strategy Behavior |
| ---------------------------------------------- | ------------------------------------------------------------------------------------ |
| `FeedbackStrategies.Always` | Always show errors |
| `FeedbackStrategies.Touched` | Show errors for fields which have been touched (changed or blurred) |
| `FeedbackStrategies.Changed` | Show errors for fields which have been changed |
| `FeedbackStrategies.ClientValidationSucceeded` | Show errors for fields which have had their validations pass at any time in the past |
| `FeedbackStrategies.Pristine` | Show errors when the form has not been modified |
| `FeedbackStrategies.Submitted` | Show errors after the form has been submitted |
These simple strategies can be combined by using the `and`, `or`, and `not` functions also on the `FeedbackStrategies` object, as follows:
```js
import {FeedbackStrategies} from "formula-one";
const {Changed, Submitted, or} = FeedbackStrategies;
const myStrategy = or(Changed, Submitted);
```
### Multiple validations for a single `<Field>`
To specify multiple validations for a single field, simply run the validations in sequence and serialize their errors into a single array.
```jsx
function validate(s: string): Array<string> {
return [noShortStrings, mustHaveLettersAndNumbers, noLongStrings].flatMap(
validation => validation(s)
);
}
```
### Validations on aggregations of *Field*s
Both `<ObjectField>` and `<ArrayField>` allow a validation to be specified. You can use the `<ErrorHelper>` component to extract the errors from the link.
## Arrays in forms
Often, you may want to edit a list of items in a form. **formula-one** exposes an aggregator called `<ArrayField>`, which allows you to manipulate a list of *Field*s.
For example, imagine you have a form for a person, who has a name, but also some number of pets, who each have their own name.
```jsx
type Person = {
name: string,
pets: Array<{
name: string,
}>,
};
const emptyPerson = {
name: "",
pets: [],
};
<Form>
{(link, onSubmit) => (
<ObjectField link={link}>
{links => (
<>
<Field link={links.name}>
{(value, errors, onChange, onBlur) => (
<>
<label>Name:</label>
<input type="text" onChange={onChange} onBlur={onBlur} />
</>
)}
</Field>
<ArrayField link={links.pets}>
{(links, {addField}) => (
<ul>
{links.map((link, i) => (
<ObjectField link={link}>
{link => (
<Field link={link}>
{(value, errors, onChange, onBlur) => (
<li>
Pet #{i + 1}
<input
type="text"
value={value}
onChange={onChange}
onBlur={onBlur}
/>
</li>
)}
</Field>
)}
</ObjectField>
))}
{links.length === 0 ? "No pets :(" : null}
<button onClick={addField(links.length, {name: ""})}>
Add pet
</button>
</ul>
)}
</ArrayField>
<div>
<button onClick={onSubmit}>Submit</button>
</div>
</>
)}
</ObjectField>
)}
</Form>;
```
`<ArrayField>` exposes both an array of links to the array elements, but also an object containing mutators for the array:
- `addField(index: number, value: T)`: Add a field at a position in the array
- `removeField(index: number)`: Remove a field at a position in array
- `moveField(fromIndex: number, toIndex: number)`: Move a field in an array (preserves metadata for the field)
## Complex inputs
Even inputs which are complex can be wrapped in a `<Field>` wrapper, but validations are tracked at the field level, so you won't be able to use **formula-one** to track changes and validations below the field level.
<!-- ### Form state vs actual model -->
## Common use cases
### Form in a modal
Oftentimes, when you need to wrap a component which has a button you will use for submission, you can simply wrap that component with your `<Form>` element. The `<Form>` does not render any elements, so it will not affect your DOM hierarchy.
Example:
```jsx
<Form>
{(link, handleSubmit) => (
<Modal buttons={[<button onClick={handleSubmit}>Submit</button>]}>
<MyField link={link} />
</Modal>
)}
</Form>
```
### External validation
Oftentimes, you will want to show errors from an external source (such as the server) in your form alongside any client-side validation errors. These can be passed into your `<Form>` component using the `serverErrors` (TODO(zach): change to `externalErrors`?) prop.
These errors must be in an object with keys representing the path to the field they should be associated with. For example, the errors:
```js
const serverErrors = {
"/": "User failed to save!",
"/email": "A user with this email already exists!",
};
```
could be used in this form:
```jsx
<Form serverErrors={serverErrors}>
({(link, handleSubmit)}) => (
<>
<ObjectField link={link}>
{links => (
<>
<StringField link={links.name} />
<StringField link={links.email} />
</>
)}
</ObjectField>
<button onClick={handleSubmit}>Submit</button>
</>
)}
</Form>
```
## Advanced usage
### Additional information in render prop
Additional information is available in an object which is the last argument to the `<Form>`, `<ObjectField>`, `<ArrayField>`, and `<Field>` components' render props. This object contains the following information:
| key | type | description |
| ----------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| touched | `boolean` | Whether the field has been touched (blurred or changed) |
| ch}anged | `boolean` | Whether the field has been changed |
| shouldShowErrors | `boolean` | Whether errors should be shown according to the current feedback strategy |
| unfilteredErrors | `$ReadOnlyArray<string>` | All validation errors for the current field. (This differs from the `errors` argument in `<Field>`, since the `errors` argument in `<Field>` will be empty if `shouldShowErrors` is false) |
| valid | `boolean` | Whether the field (and its children) pass their validations (NOTE: only client errors are considered!) |
| asyncValidationInFlight | `boolean` | Whether there is an asynchronous validation in progress for this field |
| value | `T` | The current value for this field. (This will always match the `value` argument to `<Field>`) |
An example of how these data could be used:
```jsx
<Form onSubmit={handleSubmit}>
({(link, handleSubmit, {valid})}) => (
<>
<Field link={link}>
{(value, errors, onChange, onBlur, {changed}) => (
<label>
Name
<input
type="text"
value={value}
onChange={onChange}
onBlur={onBlur}
/>
{changed ? "(Modified)" : null}
</label>
)}
</Field>
<button disabled={!valid} onClick={() => handleSubmit()}>
Submit
</button>
</>
)}
</Form>
```
### Multiple submission buttons
Sometimes, you need to have multiple submission buttons and need to know which button was clicked in your `onSubmit` prop callback. This can be achieved by passing additional information as an argument to the `handleSubmit` argument to your `<Form>`'s render prop. This argument will be passed to your `onSubmit` prop callback as a second argument. If your `onSubmit` prop callback is typed to make this extra data mandatory, they inner `handleSubmit` callback will require that data.
Example:
```jsx
function handleSubmit(value: User, saveOrSubmit: "save" | "submit") {
if (saveOrSubmit === "save") {
// ...
} else if (saveOrSubmit === "submit") {
// ...
}
}
<Form onSubmit={handleSubmit}>
({(link, handleSubmit)}) => (
<>
<UserField link={link} />
<div>
<button onClick={() => handleSubmit("save")}>Save</button>
<button onClick={() => handleSubmit("submit")}>Submit</button>
</div>
</>
)}
</Form>;
```
### Submitting forms externally
It is easy to sumbit a **formula-one** form using the `handleSubmit` argument provided to `<Form>`'s render prop, but sometimes you need to submit a `<Form>` from outside. This is possible using the `submit()` method available on `<Form>` along with a React ref to that `<Form>` element. This `submit()` method can also receive additional user-specified information, as stated above.
```jsx
class MyExternalButtonExample extends React.Component<Props> {
form: null | React.Element<typeof Form>;
constructor(props: Props) {
super(props);
this.form = null;
this.handleSubmitClick = this.handleSubmitClick.bind(this);
}
handleSubmitClick() {
if (this.form != null) {
this.form.submit();
}
}
render() {
<div>
<Form
ref={f => {
this.form = f;
}}
onSubmit={handleSubmit}
>
({(link, handleSubmit)}) => (<UserField link={link} />
)}
</Form>
<button onClick={this.handleSubmitClick}>Submit</button>
</div>;
}
}
```
<!-- #### Nested forms -->
<!-- #### Disjoint union -->

@@ -26,2 +26,3 @@ // @flow strict

import {pathFromPathString} from "./tree";
import {type FeedbackStrategy} from "./feedbackStrategies";

@@ -94,34 +95,2 @@ export type FormContextPayload = {

// FEATURE(zach): Change these to be mix-and-matchable (i.e. OnSubmit & OnChange, OnSuccess | OnTouch)
export type FeedbackStrategy =
| "Always"
| "OnFirstTouch" // A touch is a blur or a change
| "OnFirstChange"
| "OnFirstSuccess"
| "OnFirstSuccessOrFirstTouch"
| "OnSubmit";
function getShouldShowError(
strategy: FeedbackStrategy
): (MetaForm, MetaField) => boolean {
switch (strategy) {
case "Always":
return () => true;
case "OnFirstTouch":
return (_metaForm, meta: MetaField) => meta.touched;
case "OnFirstChange":
return (_metaForm, meta: MetaField) => meta.changed;
case "OnFirstSuccess":
return (_metaForm, meta: MetaField) => meta.succeeded;
case "OnFirstSuccessOrFirstTouch":
return (_metaForm, meta: MetaField) => meta.succeeded || meta.touched;
case "OnSubmit":
return (metaForm: MetaForm) => metaForm.submitted;
default:
// eslint-disable-next-line no-unused-expressions
(strategy: empty);
throw new Error("Unimplemented feedback strategy: " + strategy);
}
}
type Props<T, ExtraSubmitData> = {

@@ -244,6 +213,3 @@ // This is *only* used to intialize the form. Further changes will be ignored

value={{
shouldShowError: getShouldShowError(this.props.feedbackStrategy).bind(
null,
metaForm
),
shouldShowError: this.props.feedbackStrategy.bind(null, metaForm),
...metaForm,

@@ -263,3 +229,3 @@ }}

changed: getExtras(formState).meta.changed,
shouldShowErrors: getShouldShowError(this.props.feedbackStrategy)(
shouldShowErrors: this.props.feedbackStrategy(
metaForm,

@@ -266,0 +232,0 @@ getExtras(formState).meta

// @flow strict
// Just re-exports
// Just re-exports and some masssaging
import FeedbackStrategies, {and, or, not} from "./FeedbackStrategies";
export {default as Form} from "./Form";

@@ -10,5 +12,13 @@ export {default as ObjectField} from "./ObjectField";

export type {FeedbackStrategy} from "./Form";
const mergedStrategies = {
...FeedbackStrategies,
and,
or,
not,
};
export {mergedStrategies};
export type {FeedbackStrategy} from "./FeedbackStrategies";
export type {Validation, FieldLink} from "./types";
export * as TestUtils from "./TestUtils";

@@ -5,2 +5,3 @@ // @flow

import TestRenderer from "react-test-renderer";
import FeedbackStrategies from "../feedbackStrategies";
import Form, {FormContext} from "../Form";

@@ -51,3 +52,3 @@ import ObjectField from "../ObjectField";

initialValue={1}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={onSubmit}

@@ -91,3 +92,3 @@ serverErrors={{"/": ["Server error", "Another server error"]}}

}}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={onSubmit}

@@ -132,3 +133,3 @@ serverErrors={{

}}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={onSubmit}

@@ -155,3 +156,3 @@ serverErrors={{

}}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={onSubmit}

@@ -193,3 +194,3 @@ serverErrors={{

}}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={onSubmit}

@@ -261,3 +262,3 @@ serverErrors={null}

}}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={onSubmit}

@@ -306,3 +307,3 @@ serverErrors={null}

initialValue={1}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={onSubmit}

@@ -329,3 +330,3 @@ serverErrors={null}

initialValue={1}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={onSubmit}

@@ -357,3 +358,3 @@ serverErrors={null}

initialValue={1}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={onSubmit}

@@ -391,3 +392,3 @@ serverErrors={{"/": ["Server error", "Another server error"]}}

initialValue={1}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={jest.fn()}

@@ -425,3 +426,3 @@ serverErrors={{"/": ["Server error", "Another server error"]}}

initialValue={1}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={onSubmit}

@@ -447,3 +448,3 @@ serverErrors={{"/": ["Server error", "Another server error"]}}

initialValue={1}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Touched}
onSubmit={jest.fn()}

@@ -485,3 +486,3 @@ serverErrors={{"/": ["Server error", "Another server error"]}}

initialValue={1}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={onSubmit}

@@ -509,3 +510,3 @@ serverErrors={{"/": ["Server error", "Another server error"]}}

initialValue={1}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={onSubmit}

@@ -532,3 +533,3 @@ serverErrors={{"/": ["Server error", "Another server error"]}}

initialValue={1}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onSubmit={onSubmit}

@@ -558,3 +559,3 @@ serverErrors={{"/": ["Server error", "Another server error"]}}

initialValue={1}
feedbackStrategy="OnFirstTouch"
feedbackStrategy={FeedbackStrategies.Always}
onChange={onChange}

@@ -561,0 +562,0 @@ serverErrors={{"/": ["Server error", "Another server error"]}}

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc