+
+ {children || (
+ <>
+ {input}
+ {hasLabel && (
+ {label}
+ )}
+ {(isValid || isInvalid) && (
+
+ {feedback}
+
+ )}
+ >
+ )}
+
+
+ );
+ },
+));
+
+FormCheck.displayName = 'FormCheck';
+FormCheck.propTypes = propTypes;
+
+FormCheck.Input = FormCheckInput;
+FormCheck.Label = FormCheckLabel;
+
+export default FormCheck;
diff --git a/src/Form/BSFormContext.jsx b/src/Form/BSFormContext.jsx
new file mode 100644
index 0000000000..12f9ca46b3
--- /dev/null
+++ b/src/Form/BSFormContext.jsx
@@ -0,0 +1,7 @@
+import React from 'react';
+
+const FormContext = React.createContext({
+ controlId: undefined,
+});
+
+export default FormContext;
diff --git a/src/Form/BSFormControl.jsx b/src/Form/BSFormControl.jsx
new file mode 100644
index 0000000000..be564f6abc
--- /dev/null
+++ b/src/Form/BSFormControl.jsx
@@ -0,0 +1,187 @@
+import classNames from 'classnames';
+import PropTypes from 'prop-types';
+// import all from 'prop-types-extra/lib/all';
+import React, { useContext } from 'react';
+// import warning from 'warning';
+import Feedback from './BSFeedback';
+import FormContext from './BSFormContext';
+// import { useBootstrapPrefix } from './ThemeProvider';
+// import { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers';
+
+const propTypes = {
+ /**
+ * @default {'form-control'}
+ */
+ bsPrefix: PropTypes.string,
+
+ /**
+ * A seperate bsPrefix used for custom controls
+ *
+ * @default 'custom'
+ */
+ bsCustomPrefix: PropTypes.string,
+
+ /**
+ * The FormControl `ref` will be forwarded to the underlying input element,
+ * which means unless `as` is a composite component,
+ * it will be a DOM node, when resolved.
+ *
+ * @type {ReactRef}
+ * @alias ref
+ */
+ _ref: PropTypes.any,
+ /**
+ * Input size variants
+ *
+ * @type {('sm'|'lg')}
+ */
+ size: PropTypes.string,
+
+ /**
+ * The size attribute of the underlying HTML element.
+ * Specifies the visible width in characters if `as` is `'input'`.
+ * Specifies the number of visible options if `as` is `'select'`.
+ */
+ htmlSize: PropTypes.number,
+
+ /**
+ * The underlying HTML element to use when rendering the FormControl.
+ *
+ * @type {('input'|'textarea'|'select'|elementType)}
+ */
+ as: PropTypes.elementType,
+
+ /**
+ * Render the input as plain text. Generally used along side `readOnly`.
+ */
+ plaintext: PropTypes.bool,
+
+ /** Make the control readonly */
+ readOnly: PropTypes.bool,
+
+ /** Make the control disabled */
+ disabled: PropTypes.bool,
+
+ /**
+ * The `value` attribute of underlying input
+ *
+ * @controllable onChange
+ * */
+ value: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.arrayOf(PropTypes.string),
+ PropTypes.number,
+ ]),
+
+ /** A callback fired when the `value` prop changes */
+ onChange: PropTypes.func,
+
+ /**
+ * Use Bootstrap's custom form elements to replace the browser defaults
+ * @type boolean
+ */
+ // custom: all(PropTypes.bool, ({ as, type, custom }) => (custom === true && type !== 'range' && as !== 'select'
+ // ? Error(
+ // '`custom` can only be set to `true` when the input type is `range`, or `select`',
+ // )
+ // : null)),
+
+ /**
+ * The HTML input `type`, which is only relevant if `as` is `'input'` (the default).
+ */
+ type: PropTypes.string,
+
+ /**
+ * Uses `controlId` from `