UNPKG

@alice-ui/react

Version:
170 lines (167 loc) 4.6 kB
import { removeDataAttributes, useSlot } from "./chunk-WEE4YWWX.mjs"; // src/text-field/text-field.tsx import { clsx } from "@alice-ui/shared-utils"; import { textField } from "@alice-ui/theme"; import { filterDOMProps } from "@react-aria/utils"; import { useControlledState } from "@react-stately/utils"; import { createContext, forwardRef, useCallback, useMemo, useRef, useState } from "react"; import { useTextField } from "react-aria"; import { InputContext, Label, Provider, Text, TextAreaContext, useContextProps } from "react-aria-components"; import { jsx, jsxs } from "react/jsx-runtime"; var TextFieldContext = createContext(null); function TextField(props, ref) { [props, ref] = useContextProps(props, ref, TextFieldContext); let inputRef = useRef(null); let [labelRef, label] = useSlot(); let [inputElementType, setInputElementType] = useState("input"); const { onValueChange = () => { }, onClear, className, classNames, children, label: labelValue, description, errorMessage } = props; const handleValueChange = useCallback( (value) => { onValueChange(value != null ? value : ""); }, [onValueChange] ); const [inputValue, setInputValue] = useControlledState( props.value, props.defaultValue, handleValueChange ); const handleValueClear = useCallback(() => { setInputValue(""); onClear == null ? void 0 : onClear(); }, [onClear, setInputValue]); let { labelProps, inputProps, descriptionProps, errorMessageProps } = useTextField( { ...removeDataAttributes(props), value: inputValue, inputElementType, label, onChange: setInputValue }, inputRef ); let inputOrTextAreaRef = useCallback((el) => { inputRef.current = el; if (el) { setInputElementType(el instanceof HTMLTextAreaElement ? "textarea" : "input"); } }, []); const baseStyles = clsx(classNames == null ? void 0 : classNames.base, className); const slots = useMemo(() => textField(), []); const hasHelper = !!description || !!errorMessage; const helpComponent = useMemo(() => { if (!hasHelper) return null; return errorMessage ? /* @__PURE__ */ jsx( Text, { slot: "errorMessage", elementType: "div", className: slots.errorMessage({ class: classNames == null ? void 0 : classNames.errorMessage }), ...errorMessageProps, children: errorMessage } ) : description ? /* @__PURE__ */ jsx( Text, { slot: "description", elementType: "div", className: slots.description({ class: classNames == null ? void 0 : classNames.description }), ...descriptionProps, children: description } ) : null; }, [ classNames == null ? void 0 : classNames.description, classNames == null ? void 0 : classNames.errorMessage, description, descriptionProps, errorMessage, errorMessageProps, hasHelper, slots ]); return /* @__PURE__ */ jsx( "div", { ...filterDOMProps(props), className: slots.base({ class: baseStyles }), ref, slot: props.slot || void 0, "data-disabled": props.isDisabled || void 0, "data-invalid": props.isInvalid || void 0, "data-required": props.isRequired || void 0, "data-readonly": props.isReadOnly || void 0, "data-orientation": props.orientation || "vertical", children: /* @__PURE__ */ jsxs( Provider, { values: [ [ InputContext, { ...inputProps, "data-value": inputValue, onClear: onClear ? handleValueClear : void 0, ref: inputOrTextAreaRef } ], [ TextAreaContext, { ...inputProps, "data-value": inputValue, onClear: onClear ? handleValueClear : void 0, ref: inputOrTextAreaRef } ] ], children: [ labelValue && /* @__PURE__ */ jsx( Label, { ...labelProps, ref: labelRef, className: slots.label({ class: classNames == null ? void 0 : classNames.label }), children: labelValue } ), children, helpComponent ] } ) } ); } var _TextField = forwardRef(TextField); export { TextFieldContext, _TextField };