fix: session input with textarea now centers content correctly

pull/3137/head
yougotwill 8 months ago
parent d52461aecc
commit 8260f0481b

@ -16,8 +16,9 @@ import { ConversationTypeEnum } from '../../models/types';
const StyledInputContainer = styled(Flex)`
textarea {
cursor: default;
overflow: hidden;
padding-top: var(--margins-xs);
top: 14px;
}
`;

@ -1,4 +1,4 @@
import { ChangeEvent, ReactNode, RefObject, useEffect, useState } from 'react';
import { ChangeEvent, ReactNode, RefObject, useEffect, useRef, useState } from 'react';
import { motion } from 'framer-motion';
import { isEmpty, isEqual } from 'lodash';
@ -13,7 +13,7 @@ type TextSizes = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
const StyledSessionInput = styled(Flex)<{
error: boolean;
textSize?: TextSizes;
textSize: TextSizes;
}>`
position: relative;
width: 100%;
@ -68,6 +68,7 @@ const StyledBorder = styled(AnimatedFlex)`
const StyledInput = styled(motion.input)<{
error: boolean;
textSize: TextSizes;
centerText?: boolean;
monospaced?: boolean;
}>`
@ -79,9 +80,9 @@ const StyledInput = styled(motion.input)<{
color: ${props => (props.error ? 'var(--danger-color)' : 'var(--input-text-color)')};
font-family: ${props => (props.monospaced ? 'var(--font-mono)' : 'var(--font-default)')};
font-size: 12px;
line-height: 1.4;
${props => props.centerText && 'text-align: center;'}
${props => `font-size: var(--font-size-${props.textSize});`}
&::placeholder {
color: var(--input-text-placeholder-color);
@ -89,13 +90,15 @@ const StyledInput = styled(motion.input)<{
}
`;
const StyledTextAreaContainer = styled(motion.div)<{
export const StyledTextAreaContainer = styled(motion.div)<{
noValue: boolean;
error: boolean;
textSize: TextSizes;
centerText?: boolean;
textSize?: TextSizes;
monospaced?: boolean;
}>`
display: flex;
align-items: center;
overflow: hidden;
position: relative;
height: ${props => (props.textSize ? `calc(var(--font-size-${props.textSize}) * 4)` : '48px')};
@ -107,8 +110,8 @@ const StyledTextAreaContainer = styled(motion.div)<{
outline: 0;
font-family: ${props => (props.monospaced ? 'var(--font-mono)' : 'var(--font-default)')};
font-size: 12px;
line-height: 1.4;
${props => `font-size: var(--font-size-${props.textSize});`}
line-height: 1;
${props => props.centerText && 'text-align: center;'}
@ -121,21 +124,20 @@ const StyledTextAreaContainer = styled(motion.div)<{
border: none;
background: transparent;
${props =>
props.noValue &&
`position: absolute;
top: ${props.textSize ? `calc(var(--font-size-${props.textSize}) + 5px)` : 'calc(12px + 5px)'};`}
position: absolute;
top: ${props =>
`calc(var(--font-size-${props.textSize}) + ${props.textSize === 'xl' ? '8px' : '5px'})`};
resize: none;
overflow-wrap: break-word;
word-break: break-all;
user-select: all;
${props => props.centerText && 'text-align: center;'}
&:placeholder-shown {
font-family: ${props => (props.monospaced ? 'var(--font-mono)' : 'var(--font-default)')};
font-size: 12px;
line-height: 1.4;
${props => `font-size: var(--font-size-${props.textSize});`}
line-height: 1;
}
&::placeholder {
@ -267,7 +269,7 @@ export const SessionInput = (props: Props) => {
showHideButtonDataTestIds,
ctaButton,
monospaced,
textSize,
textSize = 'sm',
centerText,
editable = true,
isTextArea,
@ -280,6 +282,8 @@ export const SessionInput = (props: Props) => {
const [textErrorStyle, setTextErrorStyle] = useState(false);
const [forceShow, setForceShow] = useState(false);
const textAreaRef = useRef(inputRef?.current || null);
const correctType = forceShow ? 'text' : type;
const updateInputValue = (e: ChangeEvent<HTMLInputElement>) => {
@ -290,6 +294,16 @@ export const SessionInput = (props: Props) => {
const val = e.target.value;
setInputValue(val);
setTextErrorStyle(false);
if (isTextArea && textAreaRef && textAreaRef.current !== null) {
const scrollHeight = `${textAreaRef.current.scrollHeight}px`;
if (isEmpty(val)) {
// resets the height of the text area so it's centered if we clear the text
textAreaRef.current.style.height = 'unset';
}
if (scrollHeight !== textAreaRef.current.style.height) {
textAreaRef.current.style.height = `${textAreaRef.current.scrollHeight}px`;
}
}
if (onValueChanged) {
onValueChanged(val);
}
@ -301,6 +315,7 @@ export const SessionInput = (props: Props) => {
type: correctType,
placeholder,
value,
textSize,
disabled: !editable,
maxLength,
autoFocus,
@ -308,7 +323,6 @@ export const SessionInput = (props: Props) => {
required,
'aria-required': required,
tabIndex,
ref: inputRef,
onChange: updateInputValue,
style: { paddingInlineEnd: enableShowHideButton ? '48px' : undefined },
// just in case onChange isn't triggered
@ -372,12 +386,17 @@ export const SessionInput = (props: Props) => {
>
{isTextArea ? (
<StyledTextAreaContainer {...containerProps}>
<textarea {...inputProps} aria-label={ariaLabel || 'session input text area'} />
<textarea
{...inputProps}
ref={inputRef || textAreaRef}
aria-label={ariaLabel || 'session input text area'}
/>
</StyledTextAreaContainer>
) : (
<StyledInput
{...inputProps}
{...containerProps}
ref={inputRef}
aria-label={ariaLabel || 'session input'}
/>
)}

@ -13,6 +13,7 @@ import { CopyToClipboardButton } from '../../buttons/CopyToClipboardButton';
import { SessionIcon } from '../../icon';
import { SessionInput } from '../../inputs';
import { StyledLeftPaneOverlay } from './OverlayMessage';
import { StyledTextAreaContainer } from '../../inputs/SessionInput';
const StyledHeadingContainer = styled(Flex)`
.session-icon-button {
@ -53,9 +54,13 @@ const StyledButtonerContainer = styled.div`
`;
const StyledInputContainer = styled(Flex)`
textarea {
position: absolute;
top: 8px;
${StyledTextAreaContainer} {
margin: var(--margins-sm);
textarea {
cursor: default;
overflow: hidden;
top: 12px;
}
}
`;

Loading…
Cancel
Save