@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
JavaScript
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