@momentum-ui/react-collaboration
Version:
Cisco Momentum UI Framework for React Collaboration Applications
95 lines • 6.09 kB
JavaScript
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';
/**
* @deprecated Use the equivalent from momentum.design (NPM: `@momentum-design/components/dist/react`)
*/
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
*/
/**
* @deprecated Use the equivalent from momentum.design (NPM: `@momentum-design/components/dist/react`)
*/
var _TextInput = forwardRef(TextInput);
_TextInput.displayName = 'TextInput';
export default _TextInput;
//# sourceMappingURL=TextInput.js.map