177 lines
5.1 KiB
JavaScript
177 lines
5.1 KiB
JavaScript
'use client'
|
|
|
|
// src/form-control.tsx
|
|
import { createContext } from "@chakra-ui/react-context";
|
|
import { mergeRefs } from "@chakra-ui/react-use-merge-refs";
|
|
import {
|
|
chakra,
|
|
forwardRef,
|
|
omitThemingProps,
|
|
useMultiStyleConfig
|
|
} from "@chakra-ui/system";
|
|
import { cx, dataAttr } from "@chakra-ui/shared-utils";
|
|
import { useCallback, useId, useState } from "react";
|
|
import { jsx } from "react/jsx-runtime";
|
|
var [FormControlStylesProvider, useFormControlStyles] = createContext({
|
|
name: `FormControlStylesContext`,
|
|
errorMessage: `useFormControlStyles returned is 'undefined'. Seems you forgot to wrap the components in "<FormControl />" `
|
|
});
|
|
var [FormControlProvider, useFormControlContext] = createContext({
|
|
strict: false,
|
|
name: "FormControlContext"
|
|
});
|
|
function useFormControlProvider(props) {
|
|
const {
|
|
id: idProp,
|
|
isRequired,
|
|
isInvalid,
|
|
isDisabled,
|
|
isReadOnly,
|
|
...htmlProps
|
|
} = props;
|
|
const uuid = useId();
|
|
const id = idProp || `field-${uuid}`;
|
|
const labelId = `${id}-label`;
|
|
const feedbackId = `${id}-feedback`;
|
|
const helpTextId = `${id}-helptext`;
|
|
const [hasFeedbackText, setHasFeedbackText] = useState(false);
|
|
const [hasHelpText, setHasHelpText] = useState(false);
|
|
const [isFocused, setFocus] = useState(false);
|
|
const getHelpTextProps = useCallback(
|
|
(props2 = {}, forwardedRef = null) => ({
|
|
id: helpTextId,
|
|
...props2,
|
|
/**
|
|
* 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]
|
|
);
|
|
const getLabelProps = useCallback(
|
|
(props2 = {}, forwardedRef = null) => ({
|
|
...props2,
|
|
ref: forwardedRef,
|
|
"data-focus": dataAttr(isFocused),
|
|
"data-disabled": dataAttr(isDisabled),
|
|
"data-invalid": dataAttr(isInvalid),
|
|
"data-readonly": dataAttr(isReadOnly),
|
|
id: props2.id !== void 0 ? props2.id : labelId,
|
|
htmlFor: props2.htmlFor !== void 0 ? props2.htmlFor : id
|
|
}),
|
|
[id, isDisabled, isFocused, isInvalid, isReadOnly, labelId]
|
|
);
|
|
const getErrorMessageProps = useCallback(
|
|
(props2 = {}, forwardedRef = null) => ({
|
|
id: feedbackId,
|
|
...props2,
|
|
/**
|
|
* 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]
|
|
);
|
|
const getRootProps = useCallback(
|
|
(props2 = {}, forwardedRef = null) => ({
|
|
...props2,
|
|
...htmlProps,
|
|
ref: forwardedRef,
|
|
role: "group",
|
|
"data-focus": dataAttr(isFocused),
|
|
"data-disabled": dataAttr(isDisabled),
|
|
"data-invalid": dataAttr(isInvalid),
|
|
"data-readonly": dataAttr(isReadOnly)
|
|
}),
|
|
[htmlProps, isDisabled, isFocused, isInvalid, isReadOnly]
|
|
);
|
|
const getRequiredIndicatorProps = useCallback(
|
|
(props2 = {}, forwardedRef = null) => ({
|
|
...props2,
|
|
ref: forwardedRef,
|
|
role: "presentation",
|
|
"aria-hidden": true,
|
|
children: props2.children || "*"
|
|
}),
|
|
[]
|
|
);
|
|
return {
|
|
isRequired: !!isRequired,
|
|
isInvalid: !!isInvalid,
|
|
isReadOnly: !!isReadOnly,
|
|
isDisabled: !!isDisabled,
|
|
isFocused: !!isFocused,
|
|
onFocus: () => setFocus(true),
|
|
onBlur: () => setFocus(false),
|
|
hasFeedbackText,
|
|
setHasFeedbackText,
|
|
hasHelpText,
|
|
setHasHelpText,
|
|
id,
|
|
labelId,
|
|
feedbackId,
|
|
helpTextId,
|
|
htmlProps,
|
|
getHelpTextProps,
|
|
getErrorMessageProps,
|
|
getRootProps,
|
|
getLabelProps,
|
|
getRequiredIndicatorProps
|
|
};
|
|
}
|
|
var FormControl = forwardRef(
|
|
function FormControl2(props, ref) {
|
|
const styles = useMultiStyleConfig("Form", props);
|
|
const ownProps = omitThemingProps(props);
|
|
const {
|
|
getRootProps,
|
|
htmlProps: _,
|
|
...context
|
|
} = useFormControlProvider(ownProps);
|
|
const className = cx("chakra-form-control", props.className);
|
|
return /* @__PURE__ */ jsx(FormControlProvider, { value: context, children: /* @__PURE__ */ jsx(FormControlStylesProvider, { value: styles, children: /* @__PURE__ */ jsx(
|
|
chakra.div,
|
|
{
|
|
...getRootProps({}, ref),
|
|
className,
|
|
__css: styles["container"]
|
|
}
|
|
) }) });
|
|
}
|
|
);
|
|
FormControl.displayName = "FormControl";
|
|
var FormHelperText = forwardRef(
|
|
function FormHelperText2(props, ref) {
|
|
const field = useFormControlContext();
|
|
const styles = useFormControlStyles();
|
|
const className = cx("chakra-form__helper-text", props.className);
|
|
return /* @__PURE__ */ jsx(
|
|
chakra.div,
|
|
{
|
|
...field == null ? void 0 : field.getHelpTextProps(props, ref),
|
|
__css: styles.helperText,
|
|
className
|
|
}
|
|
);
|
|
}
|
|
);
|
|
FormHelperText.displayName = "FormHelperText";
|
|
|
|
export {
|
|
useFormControlStyles,
|
|
useFormControlContext,
|
|
FormControl,
|
|
FormHelperText
|
|
};
|
|
//# sourceMappingURL=chunk-DFWC5MHP.mjs.map
|