fix: session input with textarea now centers content correctly

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

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

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

Loading…
Cancel
Save