react-accessible-form
Advanced tools
Comparing version 1.0.0 to 1.0.1
import * as React from "react"; | ||
import classNames from "classnames"; | ||
import { FormGroupContext } from "./FormGroup.js"; | ||
import { FormGroupContext } from "./FormGroupContext.js"; | ||
export const FormControl = React.forwardRef((props, ref) => { | ||
@@ -5,0 +5,0 @@ const { |
@@ -5,2 +5,3 @@ import * as React from "react"; | ||
import { FormContext } from "./Form.js"; | ||
import { FormGroupContext } from "./FormGroupContext.js"; | ||
@@ -51,12 +52,2 @@ const renderSections = children => { | ||
}); | ||
FormGroup.displayName = "Form.Group"; | ||
export const FormGroupContext = React.createContext(); | ||
export const useGroupContext = () => { | ||
const groupContext = React.useContext(FormGroupContext); | ||
if (!groupContext) { | ||
throw new Error("useGroupContext must be used inside of a FormGroup"); | ||
} | ||
return groupContext; | ||
}; | ||
FormGroup.displayName = "Form.Group"; |
import * as React from "react"; | ||
import classNames from "classnames"; | ||
import { FormGroupContext } from "./FormGroup.js"; | ||
import { FormGroupContext } from "./FormGroupContext.js"; | ||
export const FormLabel = React.forwardRef((props, ref) => { | ||
@@ -5,0 +5,0 @@ const { |
@@ -124,6 +124,39 @@ (function (global, factory) { | ||
var FormGroupContext = React.createContext(); | ||
var _this$1 = undefined; | ||
var FormControl = React.forwardRef(function (props, ref) { | ||
_newArrowCheck(this, _this$1); | ||
var _props$as = props.as, | ||
as = _props$as === void 0 ? "input" : _props$as, | ||
className = props.className, | ||
rest = _objectWithoutProperties(props, ["as", "className"]); | ||
var groupContext = React.useContext(FormGroupContext); | ||
if (!groupContext) { | ||
throw new Error("FormControl must be used inside of a FormGroup"); | ||
} | ||
var disabled = groupContext.disabled, | ||
id = groupContext.id, | ||
required = groupContext.required; | ||
var inputProps = { | ||
className: classNames("form__control", className), | ||
disabled: disabled, | ||
id: id, | ||
required: required | ||
}; //$FlowFixMe | ||
return React.createElement(as, _objectSpread({}, inputProps, rest, { | ||
ref: ref | ||
})); | ||
}.bind(undefined)); | ||
FormControl.displayName = "Form.Control"; | ||
var _this$2 = undefined; | ||
var renderSections = function renderSections(children) { | ||
_newArrowCheck(this, _this$1); | ||
_newArrowCheck(this, _this$2); | ||
@@ -146,3 +179,3 @@ var childrenArr = React.Children.toArray(children); | ||
_newArrowCheck(this, _this$1); | ||
_newArrowCheck(this, _this$2); | ||
@@ -184,46 +217,3 @@ var _props$as = props.as, | ||
FormGroup.displayName = "Form.Group"; | ||
var FormGroupContext = React.createContext(); | ||
var useGroupContext = function useGroupContext() { | ||
_newArrowCheck(this, _this$1); | ||
var groupContext = React.useContext(FormGroupContext); | ||
if (!groupContext) { | ||
throw new Error("useGroupContext must be used inside of a FormGroup"); | ||
} | ||
return groupContext; | ||
}.bind(undefined); | ||
var _this$2 = undefined; | ||
var FormControl = React.forwardRef(function (props, ref) { | ||
_newArrowCheck(this, _this$2); | ||
var _props$as = props.as, | ||
as = _props$as === void 0 ? "input" : _props$as, | ||
className = props.className, | ||
rest = _objectWithoutProperties(props, ["as", "className"]); | ||
var groupContext = React.useContext(FormGroupContext); | ||
if (!groupContext) { | ||
throw new Error("FormControl must be used inside of a FormGroup"); | ||
} | ||
var disabled = groupContext.disabled, | ||
id = groupContext.id, | ||
required = groupContext.required; | ||
var inputProps = { | ||
className: classNames("form__control", className), | ||
disabled: disabled, | ||
id: id, | ||
required: required | ||
}; //$FlowFixMe | ||
return React.createElement(as, _objectSpread({}, inputProps, rest, { | ||
ref: ref | ||
})); | ||
}.bind(undefined)); | ||
FormControl.displayName = "Form.Control"; | ||
var _this$3 = undefined; | ||
@@ -230,0 +220,0 @@ var FormLabel = React.forwardRef(function (props, ref) { |
@@ -103,2 +103,35 @@ import { forwardRef, useMemo, createElement, createContext, useContext, Children, Fragment } from 'react'; | ||
const FormGroupContext = createContext(); | ||
const FormControl = forwardRef((props, ref) => { | ||
const { | ||
as = "input", | ||
className | ||
} = props, | ||
rest = _objectWithoutProperties(props, ["as", "className"]); | ||
const groupContext = useContext(FormGroupContext); | ||
if (!groupContext) { | ||
throw new Error("FormControl must be used inside of a FormGroup"); | ||
} | ||
const { | ||
disabled, | ||
id, | ||
required | ||
} = groupContext; | ||
const inputProps = { | ||
className: classNames("form__control", className), | ||
disabled, | ||
id, | ||
required | ||
}; //$FlowFixMe | ||
return createElement(as, _objectSpread({}, inputProps, rest, { | ||
ref | ||
})); | ||
}); | ||
FormControl.displayName = "Form.Control"; | ||
const renderSections = children => { | ||
@@ -149,35 +182,3 @@ const childrenArr = Children.toArray(children); | ||
FormGroup.displayName = "Form.Group"; | ||
const FormGroupContext = createContext(); | ||
const FormControl = forwardRef((props, ref) => { | ||
const { | ||
as = "input", | ||
className | ||
} = props, | ||
rest = _objectWithoutProperties(props, ["as", "className"]); | ||
const groupContext = useContext(FormGroupContext); | ||
if (!groupContext) { | ||
throw new Error("FormControl must be used inside of a FormGroup"); | ||
} | ||
const { | ||
disabled, | ||
id, | ||
required | ||
} = groupContext; | ||
const inputProps = { | ||
className: classNames("form__control", className), | ||
disabled, | ||
id, | ||
required | ||
}; //$FlowFixMe | ||
return createElement(as, _objectSpread({}, inputProps, rest, { | ||
ref | ||
})); | ||
}); | ||
FormControl.displayName = "Form.Control"; | ||
const FormLabel = forwardRef((props, ref) => { | ||
@@ -184,0 +185,0 @@ const { |
{ | ||
"name": "react-accessible-form", | ||
"description": "React Accessible Form handles makes layout and accessibility easy when writing forms.", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"license": "MIT", | ||
@@ -6,0 +6,0 @@ "files": [ |
112
README.md
@@ -1,2 +0,2 @@ | ||
# React Accessible Form · [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/erictooth/react-accessible-form/blob/master/LICENSE) [![npm version](https://img.shields.io/npm/v/react-accessible-form.svg?style=flat-square)](https://www.npmjs.com/package/react-accessible-form) ![test coverage](https://img.shields.io/badge/coverage-84%25-green.svg?style=flat-square) ![flow coverage](https://img.shields.io/badge/flow--coverage-100%25-brightgreen.svg?style=flat-square) ![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square) | ||
# React Accessible Form · [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/erictooth/react-accessible-form/blob/master/LICENSE) [![npm version](https://img.shields.io/npm/v/react-accessible-form.svg?style=flat-square)](https://www.npmjs.com/package/react-accessible-form) ![test coverage](https://img.shields.io/badge/coverage-100%25-brightgreen.svg?style=flat-square) ![flow coverage](https://img.shields.io/badge/flow--coverage-100%25-brightgreen.svg?style=flat-square) ![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square) | ||
@@ -7,4 +7,12 @@ React Accessible Form handles makes layout and accessibility easy when writing forms. | ||
Before | ||
```jsx | ||
<Form.Group layout="aligned" required> | ||
<Form.Label>Email Addresses</Form.Label> | ||
<Form.Control type="email" /> | ||
<small>Separated by semicolon (;)</small> | ||
</Form.Group> | ||
``` | ||
Without react-accessible-form: | ||
```jsx | ||
@@ -19,3 +27,3 @@ <div className="form-group form-group--aligned"> | ||
<input type="email" class="form-control" id="email_field" required /> | ||
<span className="form-text">Separated by semicolon (;)</span> | ||
<small>Separated by semicolon (;)</small> | ||
</div> | ||
@@ -25,24 +33,31 @@ </div> | ||
After | ||
```jsx | ||
<Form.Group layout="aligned" required> | ||
<Form.Label>Email Addresses</Form.Label> | ||
<Form.Control type="email" /> | ||
<Form.Text>Separated by semicolon (;)</Form.Text> | ||
</Form.Group> | ||
``` | ||
## Features | ||
- Generates a unique `id` for the label’s `htmlFor` and input’s `id` props and links them | ||
- Applies `classNames` in a predictable way that reduces boilerplate and provides maximum flexibility | ||
- Allows usage of any custom inputs with `render` prop on `Form.Control` | ||
- Optionally generates a unique `id` for the label’s `htmlFor` and input’s `id` props and links them | ||
- Applies BEM-formatted `classNames` to all of the components to make theming straightforward | ||
- Allows usage of any custom controls with `as` prop on `Form.Control` | ||
- Zero-overhead integration with form state libraries like [Formik](https://github.com/jaredpalmer/formik) and [React-Final-Form](https://github.com/final-form/react-final-form) | ||
- Optional tiny set of base styles that help with aligned form layouts | ||
- Optional set of base styles that help with aligned form layouts | ||
## `Form` Props | ||
### `layout?: "stacked" | "aligned"` | ||
### as | ||
Type: `React.ElementType` | ||
Required: `false` | ||
Default: `"form"` | ||
Changes the underlying element of the `Form` component. | ||
### disabled | ||
Type: `boolean` | ||
Required: `false` | ||
Default: `false` | ||
Sets the disabled prop on all children `Form.Control` components. | ||
### layout | ||
Type: `"stacked" | "aligned"` | ||
Required: `false` | ||
Default: `"stacked"` | ||
Propagates down to all of the children `Form.Group` components. `stacked` is the default, which is to set all of the children to `display: block`. `aligned` splits all of `Form.Group`’s children into two groups: "label", and "rest" so that all of the form’s labels will align to the same width. | ||
@@ -52,33 +67,52 @@ | ||
### `required?: boolean` | ||
### id | ||
Type: `string` | ||
Required: `false` | ||
Default: `UUIDv4()` | ||
The `id` to set on the `Form.Control` and associated `htmlFor` to set on the `Form.Label` | ||
### required | ||
Type: `boolean` | ||
Required: `false` | ||
Default: `false` | ||
Set classNames on the label to indicate a required field, and set the `required` prop on the `Form.Control` | ||
### `disabled?: boolean` | ||
### disabled | ||
Type: `boolean` | ||
Required: `false` | ||
Default: `false"` | ||
Set classNames on the label to indicate a disabled field, and set the `disabled` prop on the `Form.Control` | ||
## Custom Inputs | ||
## `Form.Control` Props | ||
The default behavior of `Form.Control` is to configure an `input` element and render it. If you want to use something else, like a `select`, `textarea`, or a third-party library component, you can render your own component without losing the benefits of React Accessible Form: | ||
### as | ||
Type: `React.ElementType` | ||
Required: `false` | ||
Default: `"input"` | ||
#### Examples | ||
##### Built-in element | ||
```jsx | ||
{ | ||
/* If the controls map to standard HTML attribute names, you can spread the props directly */ | ||
} | ||
<Form.Control render={props => <textarea {...props} />} />; | ||
<Form.Control as="select"> | ||
<option value="AL">Alabama</option> | ||
<option value="AK">Alaska</option> | ||
<option value="AZ">Arizona</option> | ||
</Form.Control> | ||
``` | ||
{ | ||
/* Otherwise, you can destructure the props and apply however is necessary */ | ||
} | ||
<Form.Control | ||
render={({ className, disabled, id, required }) => ( | ||
<SomeCustomInputComponent | ||
className={className} | ||
isDisabled={disabled} | ||
htmlId={id} | ||
isRequired={required} | ||
/> | ||
)} | ||
/>; | ||
##### Custom element | ||
```jsx | ||
<Form.Control as={ReactSelect} options={[{value: "AL", label: "Alabama"}]} /> | ||
``` | ||
##### Overriding props | ||
```jsx | ||
<Form.Control as={({className, ...props}) => <ReactSelect className="custom" {...props} />} /> | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
34536
22
115
0
538