@chakra-ui/form-control
Advanced tools
Comparing version 1.2.3 to 1.3.0
# Change Log | ||
## 1.3.0 | ||
### Minor Changes | ||
- [`b724a9dd9`](https://github.com/chakra-ui/chakra-ui/commit/b724a9dd9429d02c0b2c7f7deac66d3553100bdc) | ||
[#3674](https://github.com/chakra-ui/chakra-ui/pull/3674) Thanks | ||
[@codebender828](https://github.com/codebender828)! - Extract all React based | ||
utilities and types into `@chakra-ui/react-utils` | ||
* [`fa9350eff`](https://github.com/chakra-ui/chakra-ui/commit/fa9350eff0b907abd87cac98f9d758baed260596) | ||
[#3689](https://github.com/chakra-ui/chakra-ui/pull/3689) Thanks | ||
[@segunadebayo](https://github.com/segunadebayo)! - Refactor | ||
`useFormControlProvider` to return prop getters `getHelpTextProps`, | ||
`getErrorMessageProps`, and `getRootProps`. | ||
Detect helper text and error message using `ref` callback instead of | ||
`useLayoutEffect` | ||
Create `useFormControlProps` to provide a way to get the resolved form control | ||
props `isInvalid`, `isDisabled`, instead of HTML attributes. This will make it | ||
easier to integrate with number-input, checkbox, and switch. | ||
Update `aria-describedby` id to include `feedbackId` only when `isInvalid` is | ||
`true`, | ||
### Patch Changes | ||
- [`3cc77ce60`](https://github.com/chakra-ui/chakra-ui/commit/3cc77ce60681650436f764e28b4b2234c5ca6408) | ||
Thanks [@segunadebayo](https://github.com/segunadebayo)! - Fix concurrent mode | ||
issue with setting state in focus event handler. We use `withFlushSync` helper | ||
to achieve this. | ||
- Updated dependencies | ||
[[`623e782e8`](https://github.com/chakra-ui/chakra-ui/commit/623e782e80124297740a109e5c6c58cddc35b2eb), | ||
[`a58b724e9`](https://github.com/chakra-ui/chakra-ui/commit/a58b724e9c8656044f866b658f378662f2a44b46), | ||
[`b724a9dd9`](https://github.com/chakra-ui/chakra-ui/commit/b724a9dd9429d02c0b2c7f7deac66d3553100bdc)]: | ||
- @chakra-ui/hooks@1.3.0 | ||
- @chakra-ui/utils@1.5.0 | ||
- @chakra-ui/react-utils@1.1.0 | ||
- @chakra-ui/icon@1.1.4 | ||
## 1.2.3 | ||
@@ -4,0 +44,0 @@ |
@@ -12,2 +12,4 @@ "use strict"; | ||
var _reactUtils = require("@chakra-ui/react-utils"); | ||
var React = _interopRequireWildcard(require("react")); | ||
@@ -23,3 +25,3 @@ | ||
var _createContext = (0, _utils.createContext)({ | ||
var _createContext = (0, _reactUtils.createContext)({ | ||
strict: false, | ||
@@ -52,5 +54,5 @@ name: "FormControlContext" | ||
var _useBoolean = (0, _hooks.useBoolean)(), | ||
hasFeedbackText = _useBoolean[0], | ||
setHasFeedbackText = _useBoolean[1]; | ||
var _React$useState = React.useState(false), | ||
hasFeedbackText = _React$useState[0], | ||
setHasFeedbackText = _React$useState[1]; | ||
/** | ||
@@ -62,12 +64,71 @@ * Track whether the `FormHelperText` has been rendered. | ||
var _useBoolean2 = (0, _hooks.useBoolean)(), | ||
hasHelpText = _useBoolean2[0], | ||
setHasHelpText = _useBoolean2[1]; // Track whether the form element (e.g, `input`) has focus. | ||
var _React$useState2 = React.useState(false), | ||
hasHelpText = _React$useState2[0], | ||
setHasHelpText = _React$useState2[1]; // Track whether the form element (e.g, `input`) has focus. | ||
var _useBoolean3 = (0, _hooks.useBoolean)(), | ||
isFocused = _useBoolean3[0], | ||
setFocus = _useBoolean3[1]; | ||
var _useBoolean = (0, _hooks.useBoolean)(), | ||
isFocused = _useBoolean[0], | ||
setFocus = _useBoolean[1]; | ||
var context = { | ||
var getHelpTextProps = React.useCallback(function (props, forwardedRef) { | ||
if (props === void 0) { | ||
props = {}; | ||
} | ||
if (forwardedRef === void 0) { | ||
forwardedRef = null; | ||
} | ||
return _extends({ | ||
id: helpTextId | ||
}, props, { | ||
/** | ||
* Notify the field context when the help text is rendered on screen, | ||
* so we can apply the correct `aria-describedby` to the field (e.g. input, textarea). | ||
*/ | ||
ref: (0, _reactUtils.mergeRefs)(forwardedRef, function (node) { | ||
if (!node) return; | ||
setHasHelpText(true); | ||
}) | ||
}); | ||
}, [helpTextId]); | ||
var getErrorMessageProps = React.useCallback(function (props, forwardedRef) { | ||
if (props === void 0) { | ||
props = {}; | ||
} | ||
if (forwardedRef === void 0) { | ||
forwardedRef = null; | ||
} | ||
return _extends({ | ||
id: feedbackId | ||
}, props, { | ||
/** | ||
* Notify the field context when the error message is rendered on screen, | ||
* so we can apply the correct `aria-describedby` to the field (e.g. input, textarea). | ||
*/ | ||
ref: (0, _reactUtils.mergeRefs)(forwardedRef, function (node) { | ||
if (!node) return; | ||
setHasFeedbackText(true); | ||
}), | ||
"aria-live": "polite" | ||
}); | ||
}, [feedbackId]); | ||
var getRootProps = React.useCallback(function (props, forwardedRef) { | ||
if (props === void 0) { | ||
props = {}; | ||
} | ||
if (forwardedRef === void 0) { | ||
forwardedRef = null; | ||
} | ||
return _extends({}, props, htmlProps, { | ||
ref: forwardedRef, | ||
role: "group" | ||
}); | ||
}, [htmlProps]); | ||
return { | ||
isRequired: !!isRequired, | ||
@@ -78,3 +139,3 @@ isInvalid: !!isInvalid, | ||
isFocused: !!isFocused, | ||
onFocus: setFocus.on, | ||
onFocus: (0, _reactUtils.withFlushSync)(setFocus.on), | ||
onBlur: setFocus.off, | ||
@@ -89,5 +150,7 @@ hasFeedbackText: hasFeedbackText, | ||
helpTextId: helpTextId, | ||
htmlProps: htmlProps | ||
htmlProps: htmlProps, | ||
getHelpTextProps: getHelpTextProps, | ||
getErrorMessageProps: getErrorMessageProps, | ||
getRootProps: getRootProps | ||
}; | ||
return context; | ||
} | ||
@@ -107,16 +170,16 @@ | ||
var _useFormControlProvid = useFormControlProvider(ownProps), | ||
htmlProps = _useFormControlProvid.htmlProps, | ||
context = _objectWithoutPropertiesLoose(_useFormControlProvid, ["htmlProps"]); | ||
getRootProps = _useFormControlProvid.getRootProps, | ||
_ = _useFormControlProvid.htmlProps, | ||
context = _objectWithoutPropertiesLoose(_useFormControlProvid, ["getRootProps", "htmlProps"]); | ||
var _className = (0, _utils.cx)("chakra-form-control", props.className); | ||
var className = (0, _utils.cx)("chakra-form-control", props.className); | ||
var contextValue = React.useMemo(function () { | ||
return context; | ||
}, [context]); | ||
return /*#__PURE__*/React.createElement(FormControlProvider, { | ||
value: context | ||
value: contextValue | ||
}, /*#__PURE__*/React.createElement(_system.StylesProvider, { | ||
value: styles | ||
}, /*#__PURE__*/React.createElement(_system.chakra.div, _extends({ | ||
role: "group", | ||
ref: ref | ||
}, htmlProps, { | ||
className: _className, | ||
}, /*#__PURE__*/React.createElement(_system.chakra.div, _extends({}, getRootProps({}, ref), { | ||
className: className, | ||
__css: { | ||
@@ -142,26 +205,8 @@ width: "100%", | ||
var FormHelperText = /*#__PURE__*/(0, _system.forwardRef)(function (props, ref) { | ||
var _props$id; | ||
var field = useFormControlContext(); | ||
var styles = (0, _system.useStyles)(); | ||
/** | ||
* Notify the field context when the help text is rendered on screen, | ||
* so we can apply the correct `aria-describedby` to the field (e.g. input, textarea). | ||
*/ | ||
(0, _hooks.useSafeLayoutEffect)(function () { | ||
field == null ? void 0 : field.setHasHelpText.on(); | ||
return function () { | ||
return field == null ? void 0 : field.setHasHelpText.off(); | ||
}; | ||
}, []); | ||
var _className = (0, _utils.cx)("chakra-form__helper-text", props.className); | ||
return /*#__PURE__*/React.createElement(_system.chakra.div, _extends({ | ||
ref: ref, | ||
__css: styles.helperText | ||
}, props, { | ||
className: _className, | ||
id: (_props$id = props.id) != null ? _props$id : field == null ? void 0 : field.helpTextId | ||
var className = (0, _utils.cx)("chakra-form__helper-text", props.className); | ||
return /*#__PURE__*/React.createElement(_system.chakra.div, _extends({}, field == null ? void 0 : field.getHelpTextProps(props, ref), { | ||
__css: styles.helperText, | ||
className: className | ||
})); | ||
@@ -168,0 +213,0 @@ }); |
@@ -6,4 +6,2 @@ "use strict"; | ||
var _hooks = require("@chakra-ui/hooks"); | ||
var _icon = _interopRequireDefault(require("@chakra-ui/icon")); | ||
@@ -31,35 +29,15 @@ | ||
*/ | ||
var FormErrorMessage = /*#__PURE__*/(0, _system.forwardRef)(function (passedProps, ref) { | ||
var _props$id; | ||
var styles = (0, _system.useMultiStyleConfig)("FormError", passedProps); | ||
var props = (0, _system.omitThemingProps)(passedProps); | ||
var FormErrorMessage = /*#__PURE__*/(0, _system.forwardRef)(function (props, ref) { | ||
var styles = (0, _system.useMultiStyleConfig)("FormError", props); | ||
var ownProps = (0, _system.omitThemingProps)(props); | ||
var field = (0, _formControl.useFormControlContext)(); | ||
/** | ||
* Notify the field context when the error message is rendered on screen, | ||
* so we can apply the correct `aria-describedby` to the field (e.g. input, textarea). | ||
*/ | ||
(0, _hooks.useSafeLayoutEffect)(function () { | ||
field == null ? void 0 : field.setHasFeedbackText.on(); | ||
return function () { | ||
return field == null ? void 0 : field.setHasFeedbackText.off(); | ||
}; | ||
}, []); | ||
if (!(field != null && field.isInvalid)) return null; | ||
var _className = (0, _utils.cx)("chakra-form__error-message", props.className); | ||
return /*#__PURE__*/React.createElement(_system.StylesProvider, { | ||
value: styles | ||
}, /*#__PURE__*/React.createElement(_system.chakra.div, _extends({ | ||
"aria-live": "polite", | ||
ref: ref | ||
}, props, { | ||
}, /*#__PURE__*/React.createElement(_system.chakra.div, _extends({}, field == null ? void 0 : field.getErrorMessageProps(ownProps, ref), { | ||
className: (0, _utils.cx)("chakra-form__error-message", props.className), | ||
__css: _extends({ | ||
display: "flex", | ||
alignItems: "center" | ||
}, styles.text), | ||
className: _className, | ||
id: (_props$id = props.id) != null ? _props$id : field == null ? void 0 : field.feedbackId | ||
}, styles.text) | ||
}))); | ||
@@ -66,0 +44,0 @@ }); |
@@ -5,2 +5,3 @@ "use strict"; | ||
exports.useFormControl = useFormControl; | ||
exports.useFormControlProps = useFormControlProps; | ||
@@ -13,2 +14,4 @@ var _utils = require("@chakra-ui/utils"); | ||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } | ||
/** | ||
@@ -22,24 +25,57 @@ * React hook that provides the props that should be spread on to | ||
function useFormControl(props) { | ||
var _props$id; | ||
var _useFormControlProps = useFormControlProps(props), | ||
isDisabled = _useFormControlProps.isDisabled, | ||
isInvalid = _useFormControlProps.isInvalid, | ||
isReadOnly = _useFormControlProps.isReadOnly, | ||
isRequired = _useFormControlProps.isRequired, | ||
rest = _objectWithoutPropertiesLoose(_useFormControlProps, ["isDisabled", "isInvalid", "isReadOnly", "isRequired"]); | ||
return _extends({}, rest, { | ||
disabled: isDisabled, | ||
readOnly: isReadOnly, | ||
required: isRequired, | ||
"aria-invalid": (0, _utils.ariaAttr)(isInvalid), | ||
"aria-required": (0, _utils.ariaAttr)(isRequired), | ||
"aria-readonly": (0, _utils.ariaAttr)(isReadOnly) | ||
}); | ||
} | ||
function useFormControlProps(props) { | ||
var _ref, _ref2, _ref3; | ||
var field = (0, _formControl.useFormControlContext)(); | ||
var describedBy = []; // Error message must be described first in all scenarios. | ||
if (field != null && field.hasFeedbackText) describedBy.push(field.feedbackId); | ||
if (field != null && field.hasHelpText) describedBy.push(field.helpTextId); | ||
var ariaDescribedBy = describedBy.join(" "); | ||
var cleanProps = (0, _utils.omit)(props, ["isInvalid", "isDisabled", "isReadOnly", "isRequired"]); | ||
return _extends({}, cleanProps, { | ||
id: (_props$id = props.id) != null ? _props$id : field == null ? void 0 : field.id, | ||
disabled: props.disabled || props.isDisabled || (field == null ? void 0 : field.isDisabled), | ||
readOnly: props.readOnly || props.isReadOnly || (field == null ? void 0 : field.isReadOnly), | ||
required: props.required || props.isRequired || (field == null ? void 0 : field.isRequired), | ||
"aria-invalid": (0, _utils.ariaAttr)(props.isInvalid || (field == null ? void 0 : field.isInvalid)), | ||
"aria-required": (0, _utils.ariaAttr)(props.isRequired || (field == null ? void 0 : field.isRequired)), | ||
"aria-readonly": (0, _utils.ariaAttr)(props.isReadOnly || (field == null ? void 0 : field.isReadOnly)), | ||
"aria-describedby": ariaDescribedBy || undefined, | ||
onFocus: (0, _utils.callAllHandlers)(field == null ? void 0 : field.onFocus, props.onFocus), | ||
onBlur: (0, _utils.callAllHandlers)(field == null ? void 0 : field.onBlur, props.onBlur) | ||
var id = props.id, | ||
disabled = props.disabled, | ||
readOnly = props.readOnly, | ||
required = props.required, | ||
isRequired = props.isRequired, | ||
isInvalid = props.isInvalid, | ||
isReadOnly = props.isReadOnly, | ||
isDisabled = props.isDisabled, | ||
onFocus = props.onFocus, | ||
onBlur = props.onBlur, | ||
rest = _objectWithoutPropertiesLoose(props, ["id", "disabled", "readOnly", "required", "isRequired", "isInvalid", "isReadOnly", "isDisabled", "onFocus", "onBlur"]); | ||
var labelIds = []; // Error message must be described first in all scenarios. | ||
if (field != null && field.hasFeedbackText && field != null && field.isInvalid) { | ||
labelIds.push(field.feedbackId); | ||
} | ||
if (field != null && field.hasHelpText) { | ||
labelIds.push(field.helpTextId); | ||
} | ||
return _extends({}, rest, { | ||
"aria-describedby": labelIds.join(" ") || undefined, | ||
id: id != null ? id : field == null ? void 0 : field.id, | ||
isDisabled: (_ref = disabled != null ? disabled : isDisabled) != null ? _ref : field == null ? void 0 : field.isDisabled, | ||
isReadOnly: (_ref2 = readOnly != null ? readOnly : isReadOnly) != null ? _ref2 : field == null ? void 0 : field.isReadOnly, | ||
isRequired: (_ref3 = required != null ? required : isRequired) != null ? _ref3 : field == null ? void 0 : field.isRequired, | ||
isInvalid: isInvalid != null ? isInvalid : field == null ? void 0 : field.isInvalid, | ||
onFocus: (0, _utils.callAllHandlers)(field == null ? void 0 : field.onFocus, onFocus), | ||
onBlur: (0, _utils.callAllHandlers)(field == null ? void 0 : field.onBlur, onBlur) | ||
}); | ||
} | ||
//# sourceMappingURL=use-form-control.js.map |
@@ -5,5 +5,6 @@ function _extends() { _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; }; return _extends.apply(this, arguments); } | ||
import { useBoolean, useId, useSafeLayoutEffect } from "@chakra-ui/hooks"; | ||
import { useBoolean, useId } from "@chakra-ui/hooks"; | ||
import { chakra, forwardRef, omitThemingProps, StylesProvider, useMultiStyleConfig, useStyles } from "@chakra-ui/system"; | ||
import { createContext, cx, __DEV__ } from "@chakra-ui/utils"; | ||
import { cx, __DEV__ } from "@chakra-ui/utils"; | ||
import { createContext, withFlushSync, mergeRefs } from "@chakra-ui/react-utils"; | ||
import * as React from "react"; | ||
@@ -37,3 +38,3 @@ var [FormControlProvider, useFormControlContext] = createContext({ | ||
var [hasFeedbackText, setHasFeedbackText] = useBoolean(); | ||
var [hasFeedbackText, setHasFeedbackText] = React.useState(false); | ||
/** | ||
@@ -44,6 +45,65 @@ * Track whether the `FormHelperText` has been rendered. | ||
var [hasHelpText, setHasHelpText] = useBoolean(); // Track whether the form element (e.g, `input`) has focus. | ||
var [hasHelpText, setHasHelpText] = React.useState(false); // Track whether the form element (e.g, `input`) has focus. | ||
var [isFocused, setFocus] = useBoolean(); | ||
var context = { | ||
var getHelpTextProps = React.useCallback(function (props, forwardedRef) { | ||
if (props === void 0) { | ||
props = {}; | ||
} | ||
if (forwardedRef === void 0) { | ||
forwardedRef = null; | ||
} | ||
return _extends({ | ||
id: helpTextId | ||
}, props, { | ||
/** | ||
* Notify the field context when the help text is rendered on screen, | ||
* so we can apply the correct `aria-describedby` to the field (e.g. input, textarea). | ||
*/ | ||
ref: mergeRefs(forwardedRef, node => { | ||
if (!node) return; | ||
setHasHelpText(true); | ||
}) | ||
}); | ||
}, [helpTextId]); | ||
var getErrorMessageProps = React.useCallback(function (props, forwardedRef) { | ||
if (props === void 0) { | ||
props = {}; | ||
} | ||
if (forwardedRef === void 0) { | ||
forwardedRef = null; | ||
} | ||
return _extends({ | ||
id: feedbackId | ||
}, props, { | ||
/** | ||
* Notify the field context when the error message is rendered on screen, | ||
* so we can apply the correct `aria-describedby` to the field (e.g. input, textarea). | ||
*/ | ||
ref: mergeRefs(forwardedRef, node => { | ||
if (!node) return; | ||
setHasFeedbackText(true); | ||
}), | ||
"aria-live": "polite" | ||
}); | ||
}, [feedbackId]); | ||
var getRootProps = React.useCallback(function (props, forwardedRef) { | ||
if (props === void 0) { | ||
props = {}; | ||
} | ||
if (forwardedRef === void 0) { | ||
forwardedRef = null; | ||
} | ||
return _extends({}, props, htmlProps, { | ||
ref: forwardedRef, | ||
role: "group" | ||
}); | ||
}, [htmlProps]); | ||
return { | ||
isRequired: !!isRequired, | ||
@@ -54,3 +114,3 @@ isInvalid: !!isInvalid, | ||
isFocused: !!isFocused, | ||
onFocus: setFocus.on, | ||
onFocus: withFlushSync(setFocus.on), | ||
onBlur: setFocus.off, | ||
@@ -65,5 +125,7 @@ hasFeedbackText, | ||
helpTextId, | ||
htmlProps | ||
htmlProps, | ||
getHelpTextProps, | ||
getErrorMessageProps, | ||
getRootProps | ||
}; | ||
return context; | ||
} | ||
@@ -84,17 +146,14 @@ | ||
{ | ||
htmlProps | ||
getRootProps | ||
} = _useFormControlProvid, | ||
context = _objectWithoutPropertiesLoose(_useFormControlProvid, ["htmlProps"]); | ||
context = _objectWithoutPropertiesLoose(_useFormControlProvid, ["getRootProps", "htmlProps"]); | ||
var _className = cx("chakra-form-control", props.className); | ||
var className = cx("chakra-form-control", props.className); | ||
var contextValue = React.useMemo(() => context, [context]); | ||
return /*#__PURE__*/React.createElement(FormControlProvider, { | ||
value: context | ||
value: contextValue | ||
}, /*#__PURE__*/React.createElement(StylesProvider, { | ||
value: styles | ||
}, /*#__PURE__*/React.createElement(chakra.div, _extends({ | ||
role: "group", | ||
ref: ref | ||
}, htmlProps, { | ||
className: _className, | ||
}, /*#__PURE__*/React.createElement(chakra.div, _extends({}, getRootProps({}, ref), { | ||
className: className, | ||
__css: { | ||
@@ -119,24 +178,8 @@ width: "100%", | ||
export var FormHelperText = /*#__PURE__*/forwardRef((props, ref) => { | ||
var _props$id; | ||
var field = useFormControlContext(); | ||
var styles = useStyles(); | ||
/** | ||
* Notify the field context when the help text is rendered on screen, | ||
* so we can apply the correct `aria-describedby` to the field (e.g. input, textarea). | ||
*/ | ||
useSafeLayoutEffect(() => { | ||
field == null ? void 0 : field.setHasHelpText.on(); | ||
return () => field == null ? void 0 : field.setHasHelpText.off(); | ||
}, []); | ||
var _className = cx("chakra-form__helper-text", props.className); | ||
return /*#__PURE__*/React.createElement(chakra.div, _extends({ | ||
ref: ref, | ||
__css: styles.helperText | ||
}, props, { | ||
className: _className, | ||
id: (_props$id = props.id) != null ? _props$id : field == null ? void 0 : field.helpTextId | ||
var className = cx("chakra-form__helper-text", props.className); | ||
return /*#__PURE__*/React.createElement(chakra.div, _extends({}, field == null ? void 0 : field.getHelpTextProps(props, ref), { | ||
__css: styles.helperText, | ||
className: className | ||
})); | ||
@@ -143,0 +186,0 @@ }); |
function _extends() { _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; }; return _extends.apply(this, arguments); } | ||
import { useSafeLayoutEffect } from "@chakra-ui/hooks"; | ||
import Icon from "@chakra-ui/icon"; | ||
import { chakra, forwardRef, useStyles, useMultiStyleConfig, omitThemingProps, StylesProvider } from "@chakra-ui/system"; | ||
import { chakra, forwardRef, omitThemingProps, StylesProvider, useMultiStyleConfig, useStyles } from "@chakra-ui/system"; | ||
import { cx, __DEV__ } from "@chakra-ui/utils"; | ||
@@ -14,33 +13,15 @@ import * as React from "react"; | ||
*/ | ||
export var FormErrorMessage = /*#__PURE__*/forwardRef((passedProps, ref) => { | ||
var _props$id; | ||
var styles = useMultiStyleConfig("FormError", passedProps); | ||
var props = omitThemingProps(passedProps); | ||
export var FormErrorMessage = /*#__PURE__*/forwardRef((props, ref) => { | ||
var styles = useMultiStyleConfig("FormError", props); | ||
var ownProps = omitThemingProps(props); | ||
var field = useFormControlContext(); | ||
/** | ||
* Notify the field context when the error message is rendered on screen, | ||
* so we can apply the correct `aria-describedby` to the field (e.g. input, textarea). | ||
*/ | ||
useSafeLayoutEffect(() => { | ||
field == null ? void 0 : field.setHasFeedbackText.on(); | ||
return () => field == null ? void 0 : field.setHasFeedbackText.off(); | ||
}, []); | ||
if (!(field != null && field.isInvalid)) return null; | ||
var _className = cx("chakra-form__error-message", props.className); | ||
return /*#__PURE__*/React.createElement(StylesProvider, { | ||
value: styles | ||
}, /*#__PURE__*/React.createElement(chakra.div, _extends({ | ||
"aria-live": "polite", | ||
ref: ref | ||
}, props, { | ||
}, /*#__PURE__*/React.createElement(chakra.div, _extends({}, field == null ? void 0 : field.getErrorMessageProps(ownProps, ref), { | ||
className: cx("chakra-form__error-message", props.className), | ||
__css: _extends({ | ||
display: "flex", | ||
alignItems: "center" | ||
}, styles.text), | ||
className: _className, | ||
id: (_props$id = props.id) != null ? _props$id : field == null ? void 0 : field.feedbackId | ||
}, styles.text) | ||
}))); | ||
@@ -47,0 +28,0 @@ }); |
function _extends() { _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; }; return _extends.apply(this, arguments); } | ||
import { ariaAttr, callAllHandlers, omit } from "@chakra-ui/utils"; | ||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } | ||
import { ariaAttr, callAllHandlers } from "@chakra-ui/utils"; | ||
import { useFormControlContext } from "./form-control"; | ||
@@ -14,24 +16,60 @@ | ||
export function useFormControl(props) { | ||
var _props$id; | ||
var _useFormControlProps = useFormControlProps(props), | ||
{ | ||
isDisabled, | ||
isInvalid, | ||
isReadOnly, | ||
isRequired | ||
} = _useFormControlProps, | ||
rest = _objectWithoutPropertiesLoose(_useFormControlProps, ["isDisabled", "isInvalid", "isReadOnly", "isRequired"]); | ||
return _extends({}, rest, { | ||
disabled: isDisabled, | ||
readOnly: isReadOnly, | ||
required: isRequired, | ||
"aria-invalid": ariaAttr(isInvalid), | ||
"aria-required": ariaAttr(isRequired), | ||
"aria-readonly": ariaAttr(isReadOnly) | ||
}); | ||
} | ||
export function useFormControlProps(props) { | ||
var _ref, _ref2, _ref3; | ||
var field = useFormControlContext(); | ||
var describedBy = []; // Error message must be described first in all scenarios. | ||
if (field != null && field.hasFeedbackText) describedBy.push(field.feedbackId); | ||
if (field != null && field.hasHelpText) describedBy.push(field.helpTextId); | ||
var ariaDescribedBy = describedBy.join(" "); | ||
var cleanProps = omit(props, ["isInvalid", "isDisabled", "isReadOnly", "isRequired"]); | ||
return _extends({}, cleanProps, { | ||
id: (_props$id = props.id) != null ? _props$id : field == null ? void 0 : field.id, | ||
disabled: props.disabled || props.isDisabled || (field == null ? void 0 : field.isDisabled), | ||
readOnly: props.readOnly || props.isReadOnly || (field == null ? void 0 : field.isReadOnly), | ||
required: props.required || props.isRequired || (field == null ? void 0 : field.isRequired), | ||
"aria-invalid": ariaAttr(props.isInvalid || (field == null ? void 0 : field.isInvalid)), | ||
"aria-required": ariaAttr(props.isRequired || (field == null ? void 0 : field.isRequired)), | ||
"aria-readonly": ariaAttr(props.isReadOnly || (field == null ? void 0 : field.isReadOnly)), | ||
"aria-describedby": ariaDescribedBy || undefined, | ||
onFocus: callAllHandlers(field == null ? void 0 : field.onFocus, props.onFocus), | ||
onBlur: callAllHandlers(field == null ? void 0 : field.onBlur, props.onBlur) | ||
var { | ||
id, | ||
disabled, | ||
readOnly, | ||
required, | ||
isRequired, | ||
isInvalid, | ||
isReadOnly, | ||
isDisabled, | ||
onFocus, | ||
onBlur | ||
} = props, | ||
rest = _objectWithoutPropertiesLoose(props, ["id", "disabled", "readOnly", "required", "isRequired", "isInvalid", "isReadOnly", "isDisabled", "onFocus", "onBlur"]); | ||
var labelIds = []; // Error message must be described first in all scenarios. | ||
if (field != null && field.hasFeedbackText && field != null && field.isInvalid) { | ||
labelIds.push(field.feedbackId); | ||
} | ||
if (field != null && field.hasHelpText) { | ||
labelIds.push(field.helpTextId); | ||
} | ||
return _extends({}, rest, { | ||
"aria-describedby": labelIds.join(" ") || undefined, | ||
id: id != null ? id : field == null ? void 0 : field.id, | ||
isDisabled: (_ref = disabled != null ? disabled : isDisabled) != null ? _ref : field == null ? void 0 : field.isDisabled, | ||
isReadOnly: (_ref2 = readOnly != null ? readOnly : isReadOnly) != null ? _ref2 : field == null ? void 0 : field.isReadOnly, | ||
isRequired: (_ref3 = required != null ? required : isRequired) != null ? _ref3 : field == null ? void 0 : field.isRequired, | ||
isInvalid: isInvalid != null ? isInvalid : field == null ? void 0 : field.isInvalid, | ||
onFocus: callAllHandlers(field == null ? void 0 : field.onFocus, onFocus), | ||
onBlur: callAllHandlers(field == null ? void 0 : field.onBlur, onBlur) | ||
}); | ||
} | ||
//# sourceMappingURL=use-form-control.js.map |
@@ -1,2 +0,4 @@ | ||
import { ThemingProps, HTMLChakraProps } from "@chakra-ui/system"; | ||
import { HTMLChakraProps, ThemingProps } from "@chakra-ui/system"; | ||
import { PropGetter } from "@chakra-ui/react-utils"; | ||
import * as React from "react"; | ||
export interface FormControlOptions { | ||
@@ -47,16 +49,8 @@ /** | ||
isFocused: boolean; | ||
onFocus: () => void; | ||
onFocus: (event: any) => void; | ||
onBlur: () => void; | ||
hasFeedbackText: boolean; | ||
setHasFeedbackText: { | ||
readonly on: () => void; | ||
readonly off: () => void; | ||
readonly toggle: () => void; | ||
}; | ||
setHasFeedbackText: React.Dispatch<React.SetStateAction<boolean>>; | ||
hasHelpText: boolean; | ||
setHasHelpText: { | ||
readonly on: () => void; | ||
readonly off: () => void; | ||
readonly toggle: () => void; | ||
}; | ||
setHasHelpText: React.Dispatch<React.SetStateAction<boolean>>; | ||
id: string; | ||
@@ -73,3 +67,6 @@ labelId: string; | ||
}; | ||
}, "isRequired" | "isInvalid" | "isReadOnly" | "isDisabled" | "id" | "isFocused" | "onFocus" | "onBlur" | "hasFeedbackText" | "setHasFeedbackText" | "hasHelpText" | "setHasHelpText" | "labelId" | "feedbackId" | "helpTextId">; | ||
getHelpTextProps: PropGetter<any, {}>; | ||
getErrorMessageProps: PropGetter<any, {}>; | ||
getRootProps: PropGetter<any, {}>; | ||
}, "isRequired" | "isInvalid" | "isReadOnly" | "isDisabled" | "id" | "isFocused" | "onFocus" | "onBlur" | "hasFeedbackText" | "setHasFeedbackText" | "hasHelpText" | "setHasHelpText" | "labelId" | "feedbackId" | "helpTextId" | "getHelpTextProps" | "getErrorMessageProps">; | ||
export { useFormControlContext }; | ||
@@ -96,1 +93,2 @@ export interface FormControlProps extends HTMLChakraProps<"div">, ThemingProps<"FormControl">, FormControlContext { | ||
export declare const FormHelperText: import("@chakra-ui/system").ComponentWithAs<"div", HelpTextProps>; | ||
//# sourceMappingURL=form-control.d.ts.map |
@@ -15,1 +15,2 @@ import { IconProps } from "@chakra-ui/icon"; | ||
export declare const FormErrorIcon: import("@chakra-ui/system").ComponentWithAs<"svg", IconProps>; | ||
//# sourceMappingURL=form-error.d.ts.map |
@@ -34,1 +34,2 @@ import { HTMLChakraProps, ThemingProps } from "@chakra-ui/system"; | ||
export declare const RequiredIndicator: import("@chakra-ui/system").ComponentWithAs<"span", RequiredIndicatorProps>; | ||
//# sourceMappingURL=form-label.d.ts.map |
@@ -5,1 +5,2 @@ export * from "./form-control"; | ||
export * from "./form-label"; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -19,3 +19,2 @@ import { FocusEventHandler } from "react"; | ||
export declare function useFormControl<T extends HTMLElement>(props: UseFormControlProps<T>): { | ||
id: string; | ||
disabled: boolean; | ||
@@ -28,4 +27,16 @@ readOnly: boolean; | ||
"aria-describedby": string | undefined; | ||
id: string; | ||
onFocus: (event: import("react").FocusEvent<T>) => void; | ||
onBlur: (event: import("react").FocusEvent<T>) => void; | ||
}; | ||
export declare function useFormControlProps<T extends HTMLElement>(props: UseFormControlProps<T>): { | ||
"aria-describedby": string | undefined; | ||
id: string; | ||
isDisabled: boolean; | ||
isReadOnly: boolean; | ||
isRequired: boolean; | ||
isInvalid: boolean; | ||
onFocus: (event: import("react").FocusEvent<T>) => void; | ||
onBlur: (event: import("react").FocusEvent<T>) => void; | ||
}; | ||
//# sourceMappingURL=use-form-control.d.ts.map |
{ | ||
"name": "@chakra-ui/form-control", | ||
"version": "1.2.3", | ||
"version": "1.3.0", | ||
"description": "React component to provide validation states to form fields", | ||
@@ -58,8 +58,9 @@ "keywords": [ | ||
"dependencies": { | ||
"@chakra-ui/hooks": "1.2.0", | ||
"@chakra-ui/icon": "1.1.3", | ||
"@chakra-ui/utils": "1.4.0" | ||
"@chakra-ui/hooks": "1.3.0", | ||
"@chakra-ui/icon": "1.1.4", | ||
"@chakra-ui/react-utils": "1.1.0", | ||
"@chakra-ui/utils": "1.5.0" | ||
}, | ||
"devDependencies": { | ||
"@chakra-ui/system": "1.5.0", | ||
"@chakra-ui/system": "1.6.0", | ||
"react": "^17.0.1" | ||
@@ -66,0 +67,0 @@ }, |
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
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
115828
33
962
6
+ Added@chakra-ui/react-utils@1.1.0
+ Added@chakra-ui/hooks@1.3.0(transitive)
+ Added@chakra-ui/icon@1.1.4(transitive)
+ Added@chakra-ui/react-utils@1.1.0(transitive)
+ Added@chakra-ui/utils@1.5.0(transitive)
+ Addedreact-dom@18.3.1(transitive)
+ Addedscheduler@0.23.2(transitive)
- Removed@chakra-ui/hooks@1.2.0(transitive)
- Removed@chakra-ui/icon@1.1.3(transitive)
- Removed@chakra-ui/utils@1.4.0(transitive)
- Removed@types/object-assign@4.0.30(transitive)
Updated@chakra-ui/hooks@1.3.0
Updated@chakra-ui/icon@1.1.4
Updated@chakra-ui/utils@1.5.0