UNPKG

@momentum-ui/react-collaboration

Version:

Cisco Momentum UI Framework for React Collaboration Applications

89 lines 5.87 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; /* eslint-disable jsx-a11y/no-static-element-interactions */ /* eslint-disable jsx-a11y/click-events-have-key-events */ import React, { forwardRef, useRef, useEffect, useCallback, } from 'react'; import { useTextField } from '@react-aria/textfield'; import { useSearchFieldState } from '@react-stately/searchfield'; import classnames from 'classnames'; import './TextInput.style.scss'; import InputMessage, { getFilteredMessages } from '../InputMessage'; import { ButtonSimple, Icon, ScreenReaderAnnouncer } from '..'; import { STYLE } from './TextInput.constants'; import { useFocusState } from '../../hooks/useFocusState'; import { v4 as uuidV4 } from 'uuid'; import { useId } from '@react-aria/utils'; import { useSpatialNavigationContext } from '../SpatialNavigationProvider/SpatialNavigationProvider.utils'; var TextInput = function (props, ref) { var _a = props.messageArr, messageArr = _a === void 0 ? [] : _a, label = props.label, className = props.className, clearAriaLabel = props.clearAriaLabel, description = props.description, inputClassName = props.inputClassName, isDisabled = props.isDisabled, style = props.style, id = props.id, inputMaxLen = props.inputMaxLen; var ariaLabel = props['aria-label']; if (ariaLabel && label && ariaLabel === label) { console.warn("MRV2: The aria-label and visible label of the Text Input are the same, making SR read it twice. Please provide only 1. Aria-label: ".concat(ariaLabel, ". Visible label: ").concat(label)); } var componentRef = React.useRef(); var inputRef = ref || componentRef; var _b = getFilteredMessages(messageArr), messageType = _b[0], messages = _b[1]; var errorMessage = messageType === 'error' ? messages[0] : undefined; var _c = useTextField(__assign(__assign({}, props), { errorMessage: errorMessage }), inputRef), labelProps = _c.labelProps, inputProps = _c.inputProps, descriptionProps = _c.descriptionProps, errorMessageProps = _c.errorMessageProps; var _d = useFocusState(props), isFocused = _d.isFocused, focusProps = _d.focusProps; var state = useSearchFieldState(props); var messageId = useRef(uuidV4()); var labelId = useRef(uuidV4()); var clearButtonId = useRef(uuidV4()); var announcerId = useId(id); var onClearButtonPress = function () { state.setValue(''); if (inputRef.current) { inputRef.current.focus(); } }; var handleClick = function () { if (inputRef.current) { inputRef.current.focus(); } }; useEffect(function () { // Automatically SR-announce the error message as soon as it appears visibly on the screen to comply with a11y rules if (errorMessage) { ScreenReaderAnnouncer.announce({ body: errorMessage }, announcerId); } }, [announcerId, errorMessage]); var spatialNav = useSpatialNavigationContext(); var keydownHandler = useCallback(function (evt) { var _a, _b; // Usually arrow keys used for spatial navigation which interfere with the input field // But devices with spatial navigation uses on screen keyboard with virtual arrow keys if ((_b = (_a = spatialNav === null || spatialNav === void 0 ? void 0 : spatialNav.directionKeys) === null || _a === void 0 ? void 0 : _a.includes) === null || _b === void 0 ? void 0 : _b.call(_a, evt.key)) { evt.preventDefault(); } }, [spatialNav]); return (React.createElement("div", { "data-level": messageType, "data-focus": isFocused, "data-disabled": isDisabled, style: style, onClick: handleClick, onKeyDown: keydownHandler, className: classnames(STYLE.wrapper, className) }, label && (React.createElement("label", __assign({}, labelProps, { htmlFor: labelProps.htmlFor, id: labelId.current }), label)), React.createElement("div", { className: STYLE.container }, React.createElement("input", __assign({}, inputProps, focusProps, { className: inputClassName, ref: inputRef, maxLength: inputMaxLen, "aria-describedby": messages && !!messages.length ? messageId.current : undefined, "aria-invalid": messageType === 'error' ? true : undefined })), !!state.value && !isDisabled && (React.createElement(ButtonSimple, { className: "clear-icon", "aria-label": clearAriaLabel, onPress: onClearButtonPress, id: clearButtonId.current, "aria-labelledby": label ? "".concat(clearButtonId.current, " ").concat(labelId.current) : id ? "".concat(clearButtonId.current, " ").concat(id) : clearButtonId.current }, React.createElement(Icon, { scale: 18, name: "cancel" })))), !!description && !(messages === null || messages === void 0 ? void 0 : messages.length) && (React.createElement(InputMessage, __assign({ className: STYLE.help, level: "help" }, descriptionProps, { message: description }))), messages && !!messages.length && (React.createElement("div", __assign({}, errorMessageProps), messages.map(function (m, i) { return (React.createElement(InputMessage, { className: STYLE.error, message: m, key: "input-message-".concat(i), level: messageType, id: messageId.current })); }))), React.createElement(ScreenReaderAnnouncer, { identity: announcerId }))); }; /** * Short text input */ var _TextInput = forwardRef(TextInput); _TextInput.displayName = 'TextInput'; export default _TextInput; //# sourceMappingURL=TextInput.js.map