-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: remove bootstrap from Form component
- Loading branch information
1 parent
e96baef
commit b255421
Showing
7 changed files
with
584 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import classNames from 'classnames'; | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
// import { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; | ||
|
||
const propTypes = { | ||
/** | ||
* Specify whether the feedback is for valid or invalid fields | ||
* | ||
* @type {('valid'|'invalid')} | ||
*/ | ||
type: PropTypes.string, | ||
|
||
/** Display feedback as a tooltip. */ | ||
tooltip: PropTypes.bool, | ||
|
||
as: PropTypes.elementType, | ||
}; | ||
|
||
const Feedback = React.forwardRef( | ||
( | ||
{ | ||
as: Component = 'div', | ||
className, | ||
type = 'valid', | ||
tooltip = false, | ||
...props | ||
}, | ||
ref, | ||
) => ( | ||
<Component | ||
{...props} | ||
ref={ref} | ||
className={classNames( | ||
className, | ||
`${type}-${tooltip ? 'tooltip' : 'feedback'}`, | ||
)} | ||
/> | ||
), | ||
); | ||
|
||
Feedback.displayName = 'Feedback'; | ||
Feedback.propTypes = propTypes; | ||
|
||
export default Feedback; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import classNames from 'classnames'; | ||
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import FormCheck from './FormCheck'; | ||
Check failure on line 4 in src/Form/BSForm.jsx
|
||
import FormFile from './FormFile'; | ||
Check failure on line 5 in src/Form/BSForm.jsx
|
||
import FormControl from './FormControl'; | ||
import FormGroup from './FormGroup'; | ||
import FormLabel from './FormLabel'; | ||
import FormText from './FormText'; | ||
import Switch from './Switch'; | ||
Check failure on line 10 in src/Form/BSForm.jsx
|
||
// import { useBootstrapPrefix } from './ThemeProvider'; | ||
import createWithBsPrefix from './createWithBsPrefix'; | ||
// import { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; | ||
|
||
const FormRow = createWithBsPrefix('form-row'); | ||
|
||
const propTypes = { | ||
/** | ||
* @default {'form'} | ||
*/ | ||
bsPrefix: PropTypes.string, | ||
|
||
/** | ||
* The Form `ref` will be forwarded to the underlying element, | ||
* which means, unless it's rendered `as` a composite component, | ||
* it will be a DOM node, when resolved. | ||
* | ||
* @type {ReactRef} | ||
* @alias ref | ||
*/ | ||
_ref: PropTypes.any, | ||
|
||
/** | ||
* Display the series of labels, form controls, | ||
* and buttons on a single horizontal row | ||
*/ | ||
inline: PropTypes.bool, | ||
|
||
/** | ||
* Mark a form as having been validated. Setting it to `true` will | ||
* toggle any validation styles on the forms elements. | ||
*/ | ||
validated: PropTypes.bool, | ||
as: PropTypes.elementType, | ||
}; | ||
|
||
const defaultProps = { | ||
inline: false, | ||
}; | ||
|
||
const FormImpl = (React.forwardRef( | ||
( | ||
{ | ||
bsPrefix, | ||
inline, | ||
className, | ||
validated, | ||
as: Component = 'form', | ||
...props | ||
}, | ||
ref, | ||
) => { | ||
// bsPrefix = useBootstrapPrefix(bsPrefix, 'form'); | ||
bsPrefix = 'form'; | ||
return ( | ||
<Component | ||
{...props} | ||
ref={ref} | ||
className={classNames( | ||
className, | ||
validated && 'was-validated', | ||
inline && `${bsPrefix}-inline`, | ||
)} | ||
/> | ||
); | ||
}, | ||
)); | ||
|
||
FormImpl.displayName = 'Form'; | ||
FormImpl.propTypes = propTypes; | ||
FormImpl.defaultProps = defaultProps; | ||
|
||
FormImpl.Row = FormRow; | ||
FormImpl.Group = FormGroup; | ||
FormImpl.Control = FormControl; | ||
FormImpl.Check = FormCheck; | ||
FormImpl.File = FormFile; | ||
FormImpl.Switch = Switch; | ||
FormImpl.Label = FormLabel; | ||
FormImpl.Text = FormText; | ||
|
||
export default FormImpl; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
import classNames from 'classnames'; | ||
import PropTypes from 'prop-types'; | ||
// import all from 'prop-types-extra/lib/all'; | ||
import React, { useContext, useMemo } from 'react'; | ||
import Feedback from './BSFeedback'; | ||
import FormCheckInput from './FormCheckInput'; | ||
import FormCheckLabel from './FormCheckLabel'; | ||
import FormContext from './BSFormContext'; | ||
// import { useBootstrapPrefix } from './ThemeProvider'; | ||
|
||
const propTypes = { | ||
/** | ||
* @default 'form-check' | ||
*/ | ||
bsPrefix: PropTypes.string, | ||
|
||
/** | ||
* A seperate bsPrefix used for custom controls | ||
* | ||
* @default 'custom-control' | ||
*/ | ||
bsCustomPrefix: PropTypes.string, | ||
|
||
/** | ||
* The FormCheck `ref` will be forwarded to the underlying input element, | ||
* which means it will be a DOM node, when resolved. | ||
* | ||
* @type {ReactRef} | ||
* @alias ref | ||
*/ | ||
_ref: PropTypes.any, | ||
|
||
/** | ||
* The underlying HTML element to use when rendering the FormCheck. | ||
* | ||
* @type {('input'|elementType)} | ||
*/ | ||
as: PropTypes.elementType, | ||
|
||
/** | ||
* A HTML id attribute, necessary for proper form accessibility. | ||
* An id is recommended for allowing label clicks to toggle the check control. | ||
* | ||
* This is **required** for custom check controls or when `type="switch"` due to | ||
* how they are rendered. | ||
*/ | ||
id: PropTypes.string, | ||
|
||
/** | ||
* Provide a function child to manually handle the layout of the FormCheck's inner components. | ||
* | ||
* ```jsx | ||
* <FormCheck> | ||
* <FormCheck.Input isInvalid type={radio} /> | ||
* <FormCheck.Label>Allow us to contact you?</FormCheck.Label> | ||
* <Feedback type="invalid">Yo this is required</Feedback> | ||
* </FormCheck> | ||
* ``` | ||
*/ | ||
children: PropTypes.node, | ||
|
||
/** | ||
* Groups controls horizontally with other `FormCheck`s. | ||
*/ | ||
inline: PropTypes.bool, | ||
|
||
/** | ||
* Disables the control. | ||
*/ | ||
disabled: PropTypes.bool, | ||
|
||
/** | ||
* `title` attribute for the underlying `FormCheckLabel`. | ||
*/ | ||
title: PropTypes.string, | ||
|
||
/** | ||
* Label for the control. | ||
*/ | ||
label: PropTypes.node, | ||
|
||
/** Use Bootstrap's custom form elements to replace the browser defaults */ | ||
// custom: all(PropTypes.bool, ({ custom, id }) => (custom && !id ? Error('Custom check controls require an id to work') : null)), | ||
|
||
/** | ||
* The type of checkable. | ||
* @type {('radio' | 'checkbox' | 'switch')} | ||
*/ | ||
type: all( | ||
PropTypes.oneOf(['radio', 'checkbox', 'switch']).isRequired, | ||
({ type, custom }) => (type === 'switch' && custom === false | ||
? Error('`custom` cannot be set to `false` when the type is `switch`') | ||
: null), | ||
({ type, id }) => (type === 'switch' && !id | ||
? Error('`id` must be defined when the type is `switch`') | ||
: null), | ||
), | ||
|
||
/** Manually style the input as valid */ | ||
isValid: PropTypes.bool, | ||
|
||
/** Manually style the input as invalid */ | ||
isInvalid: PropTypes.bool, | ||
|
||
/** Display feedback as a tooltip. */ | ||
feedbackTooltip: PropTypes.bool, | ||
|
||
/** A message to display when the input is in a validation state */ | ||
feedback: PropTypes.node, | ||
}; | ||
|
||
const FormCheck = (React.forwardRef( | ||
( | ||
{ | ||
id, | ||
bsPrefix, | ||
bsCustomPrefix, | ||
inline = false, | ||
disabled = false, | ||
isValid = false, | ||
isInvalid = false, | ||
feedbackTooltip = false, | ||
feedback, | ||
className, | ||
style, | ||
title = '', | ||
type = 'checkbox', | ||
label, | ||
children, | ||
custom: propCustom, | ||
as = 'input', | ||
...props | ||
}, | ||
ref, | ||
) => { | ||
const custom = type === 'switch' ? true : propCustom; | ||
const [prefix, defaultPrefix] = custom | ||
? [bsCustomPrefix, 'custom-control'] | ||
: [bsPrefix, 'form-check']; | ||
|
||
// bsPrefix = useBootstrapPrefix(prefix, defaultPrefix); | ||
bsPrefix = 'form-check'; | ||
|
||
const { controlId } = useContext(FormContext); | ||
const innerFormContext = useMemo( | ||
() => ({ | ||
controlId: id || controlId, | ||
custom, | ||
}), | ||
[controlId, custom, id], | ||
); | ||
|
||
const hasLabel = custom || (label != null && label !== false && !children); | ||
|
||
const input = ( | ||
<FormCheckInput | ||
{...props} | ||
type={type === 'switch' ? 'checkbox' : type} | ||
ref={ref} | ||
isValid={isValid} | ||
isInvalid={isInvalid} | ||
isStatic={!hasLabel} | ||
disabled={disabled} | ||
as={as} | ||
/> | ||
); | ||
|
||
return ( | ||
<FormContext.Provider value={innerFormContext}> | ||
<div | ||
style={style} | ||
className={classNames( | ||
className, | ||
bsPrefix, | ||
custom && `custom-${type}`, | ||
inline && `${bsPrefix}-inline`, | ||
)} | ||
> | ||
{children || ( | ||
<> | ||
{input} | ||
{hasLabel && ( | ||
<FormCheckLabel title={title}>{label}</FormCheckLabel> | ||
)} | ||
{(isValid || isInvalid) && ( | ||
<Feedback | ||
type={isValid ? 'valid' : 'invalid'} | ||
tooltip={feedbackTooltip} | ||
> | ||
{feedback} | ||
</Feedback> | ||
)} | ||
</> | ||
)} | ||
</div> | ||
</FormContext.Provider> | ||
); | ||
}, | ||
)); | ||
|
||
FormCheck.displayName = 'FormCheck'; | ||
FormCheck.propTypes = propTypes; | ||
|
||
FormCheck.Input = FormCheckInput; | ||
FormCheck.Label = FormCheckLabel; | ||
|
||
export default FormCheck; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
|
||
const FormContext = React.createContext({ | ||
controlId: undefined, | ||
}); | ||
|
||
export default FormContext; |
Oops, something went wrong.