UNPKG

@awsui/components-react

Version:

On July 19th, 2022, we launched [Cloudscape Design System](https://cloudscape.design). Cloudscape is an evolution of AWS-UI. It consists of user interface guidelines, front-end components, design resources, and development tools for building intuitive, en

130 lines • 7.89 kB
import { __rest } from "tslib"; // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import React, { useCallback, useEffect, useImperativeHandle, useRef } from 'react'; import clsx from 'clsx'; import { useDensityMode } from '@awsui/component-toolkit/internal'; import InternalButton from '../button/internal'; import { convertAutoComplete } from '../input/utils'; import { getBaseProps } from '../internal/base-component'; import { useFormFieldContext } from '../internal/context/form-field-context'; import { fireKeyboardEvent, fireNonCancelableEvent } from '../internal/events'; import * as tokens from '../internal/generated/styles/tokens'; import { useVisualRefresh } from '../internal/hooks/use-visual-mode'; import styles from './styles.css.js'; import testutilStyles from './test-classes/styles.css.js'; const InternalPromptInput = React.forwardRef((_a, ref) => { var { value, actionButtonAriaLabel, actionButtonIconName, actionButtonIconUrl, actionButtonIconSvg, actionButtonIconAlt, ariaLabel, autoComplete, autoFocus, disableActionButton, disableBrowserAutocorrect, disabled, maxRows, minRows, name, onAction, onBlur, onChange, onFocus, onKeyDown, onKeyUp, placeholder, readOnly, spellcheck, secondaryActions, secondaryContent, disableSecondaryActionsPaddings, disableSecondaryContentPaddings, __internalRootRef = null } = _a, rest = __rest(_a, ["value", "actionButtonAriaLabel", "actionButtonIconName", "actionButtonIconUrl", "actionButtonIconSvg", "actionButtonIconAlt", "ariaLabel", "autoComplete", "autoFocus", "disableActionButton", "disableBrowserAutocorrect", "disabled", "maxRows", "minRows", "name", "onAction", "onBlur", "onChange", "onFocus", "onKeyDown", "onKeyUp", "placeholder", "readOnly", "spellcheck", "secondaryActions", "secondaryContent", "disableSecondaryActionsPaddings", "disableSecondaryContentPaddings", "__internalRootRef"]); const { ariaLabelledby, ariaDescribedby, controlId, invalid, warning } = useFormFieldContext(rest); const baseProps = getBaseProps(rest); const textareaRef = useRef(null); const isRefresh = useVisualRefresh(); const isCompactMode = useDensityMode(textareaRef) === 'compact'; const PADDING = isRefresh ? tokens.spaceXxs : tokens.spaceXxxs; const LINE_HEIGHT = tokens.lineHeightBodyM; useImperativeHandle(ref, () => ({ focus(...args) { var _a; (_a = textareaRef.current) === null || _a === void 0 ? void 0 : _a.focus(...args); }, select() { var _a; (_a = textareaRef.current) === null || _a === void 0 ? void 0 : _a.select(); }, setSelectionRange(...args) { var _a; (_a = textareaRef.current) === null || _a === void 0 ? void 0 : _a.setSelectionRange(...args); }, }), [textareaRef]); const handleKeyDown = (event) => { fireKeyboardEvent(onKeyDown, event); if (event.key === 'Enter' && !event.shiftKey) { if ('form' in event.target && event.target.form !== null && !event.isDefaultPrevented()) { event.target.form.requestSubmit(); } event.preventDefault(); fireNonCancelableEvent(onAction, { value }); } }; const handleChange = (event) => { fireNonCancelableEvent(onChange, { value: event.target.value }); adjustTextareaHeight(); }; const hasActionButton = actionButtonIconName || actionButtonIconSvg || actionButtonIconUrl; const adjustTextareaHeight = useCallback(() => { if (textareaRef.current) { textareaRef.current.style.height = 'auto'; const maxRowsHeight = `calc(${maxRows <= 0 ? 3 : maxRows} * (${LINE_HEIGHT} + ${PADDING} / 2) + ${PADDING})`; const scrollHeight = `calc(${textareaRef.current.scrollHeight}px)`; const minTextareaHeight = `calc(${LINE_HEIGHT} + ${tokens.spaceScaledXxs} * 2)`; // the min height of Textarea with 1 row textareaRef.current.style.height = `min(max(${scrollHeight}, ${minTextareaHeight}), ${maxRowsHeight})`; } }, [maxRows, LINE_HEIGHT, PADDING]); useEffect(() => { const handleResize = () => { adjustTextareaHeight(); }; window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); }; }, [adjustTextareaHeight]); useEffect(() => { adjustTextareaHeight(); }, [value, adjustTextareaHeight, maxRows, isCompactMode]); const attributes = { 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, 'aria-describedby': ariaDescribedby, 'aria-invalid': invalid ? 'true' : undefined, name, placeholder, autoFocus, className: clsx(styles.textarea, testutilStyles.textarea, { [styles.invalid]: invalid, [styles.warning]: warning, }), autoComplete: convertAutoComplete(autoComplete), spellCheck: spellcheck, disabled, readOnly: readOnly ? true : undefined, rows: minRows, onKeyDown: handleKeyDown, onKeyUp: onKeyUp && (event => fireKeyboardEvent(onKeyUp, event)), // We set a default value on the component in order to force it into the controlled mode. value: value || '', onChange: handleChange, onBlur: onBlur && (() => fireNonCancelableEvent(onBlur)), onFocus: onFocus && (() => fireNonCancelableEvent(onFocus)), }; if (disableBrowserAutocorrect) { attributes.autoCorrect = 'off'; attributes.autoCapitalize = 'off'; } const action = (React.createElement("div", { className: styles.button }, React.createElement(InternalButton, { className: clsx(styles['action-button'], testutilStyles['action-button']), ariaLabel: actionButtonAriaLabel, disabled: disabled || readOnly || disableActionButton, __focusable: readOnly, iconName: actionButtonIconName, iconUrl: actionButtonIconUrl, iconSvg: actionButtonIconSvg, iconAlt: actionButtonIconAlt, onClick: () => fireNonCancelableEvent(onAction, { value }), variant: "icon" }))); return (React.createElement("div", Object.assign({}, baseProps, { "aria-label": ariaLabel, className: clsx(styles.root, testutilStyles.root, baseProps.className, { [styles['textarea-readonly']]: readOnly, [styles['textarea-invalid']]: invalid, [styles['textarea-warning']]: warning && !invalid, [styles.disabled]: disabled, }), ref: __internalRootRef, role: "region" }), secondaryContent && (React.createElement("div", { className: clsx(styles['secondary-content'], testutilStyles['secondary-content'], { [styles['with-paddings']]: !disableSecondaryContentPaddings, [styles.invalid]: invalid, [styles.warning]: warning, }) }, secondaryContent)), React.createElement("div", { className: styles['textarea-wrapper'] }, React.createElement("textarea", Object.assign({ ref: textareaRef, id: controlId }, attributes)), hasActionButton && !secondaryActions && action), secondaryActions && (React.createElement("div", { className: clsx(styles['secondary-actions'], testutilStyles['secondary-actions'], { [styles['with-paddings']]: !disableSecondaryActionsPaddings, [styles.invalid]: invalid, [styles.warning]: warning, }) }, secondaryActions, React.createElement("div", { className: styles.buffer, onClick: () => { var _a; return (_a = textareaRef.current) === null || _a === void 0 ? void 0 : _a.focus(); } }), hasActionButton && action)))); }); export default InternalPromptInput; //# sourceMappingURL=internal.js.map