2
0

feat(engine): 💄 Better long text input

This commit is contained in:
Baptiste Arnaud
2022-04-29 19:46:38 -07:00
parent cff5ec67de
commit e339cc1672
4 changed files with 45 additions and 20 deletions

View File

@@ -186,6 +186,7 @@ export const ChatBlock = ({
isEnabled: typebot.theme.chat.hostAvatar?.isEnabled ?? true, isEnabled: typebot.theme.chat.hostAvatar?.isEnabled ?? true,
src: avatarSrc && parseVariables(typebot.variables)(avatarSrc), src: avatarSrc && parseVariables(typebot.variables)(avatarSrc),
}} }}
hasGuestAvatar={typebot.theme.chat.guestAvatar?.isEnabled ?? false}
onDisplayNextStep={displayNextStep} onDisplayNextStep={displayNextStep}
/> />
))} ))}
@@ -197,11 +198,13 @@ export const ChatBlock = ({
type Props = { type Props = {
displayChunk: ChatDisplayChunk displayChunk: ChatDisplayChunk
hostAvatar: { isEnabled: boolean; src?: string } hostAvatar: { isEnabled: boolean; src?: string }
hasGuestAvatar: boolean
onDisplayNextStep: (answerContent?: string, isRetry?: boolean) => void onDisplayNextStep: (answerContent?: string, isRetry?: boolean) => void
} }
const ChatChunks = ({ const ChatChunks = ({
displayChunk: { bubbles, input }, displayChunk: { bubbles, input },
hostAvatar, hostAvatar,
hasGuestAvatar,
onDisplayNextStep, onDisplayNextStep,
}: Props) => { }: Props) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -223,7 +226,10 @@ const ChatChunks = ({
hostAvatarSrc={hostAvatar.src} hostAvatarSrc={hostAvatar.src}
/> />
)} )}
<div className="flex-1" style={{ marginRight: '50px' }}> <div
className="flex-1"
style={{ marginRight: hasGuestAvatar ? '50px' : '0.5rem' }}
>
<TransitionGroup> <TransitionGroup>
{bubbles.map((step) => ( {bubbles.map((step) => (
<CSSTransition <CSSTransition
@@ -255,6 +261,7 @@ const ChatChunks = ({
step={input} step={input}
onTransitionEnd={onDisplayNextStep} onTransitionEnd={onDisplayNextStep}
hasAvatar={hostAvatar.isEnabled} hasAvatar={hostAvatar.isEnabled}
hasGuestAvatar={hasGuestAvatar}
/> />
)} )}
</CSSTransition> </CSSTransition>

View File

@@ -13,9 +13,11 @@ import { isInputValid } from 'services/inputs'
export const InputChatStep = ({ export const InputChatStep = ({
step, step,
hasAvatar, hasAvatar,
hasGuestAvatar,
onTransitionEnd, onTransitionEnd,
}: { }: {
step: InputStep step: InputStep
hasGuestAvatar: boolean
hasAvatar: boolean hasAvatar: boolean
onTransitionEnd: (answerContent?: string, isRetry?: boolean) => void onTransitionEnd: (answerContent?: string, isRetry?: boolean) => void
}) => { }) => {
@@ -70,6 +72,7 @@ export const InputChatStep = ({
step={step} step={step}
onSubmit={handleSubmit} onSubmit={handleSubmit}
defaultValue={defaultValue?.toString()} defaultValue={defaultValue?.toString()}
hasGuestAvatar={hasGuestAvatar}
/> />
</div> </div>
) )
@@ -79,10 +82,12 @@ const Input = ({
step, step,
onSubmit, onSubmit,
defaultValue, defaultValue,
hasGuestAvatar,
}: { }: {
step: InputStep step: InputStep
onSubmit: (value: string) => void onSubmit: (value: string) => void
defaultValue?: string defaultValue?: string
hasGuestAvatar: boolean
}) => { }) => {
switch (step.type) { switch (step.type) {
case InputStepType.TEXT: case InputStepType.TEXT:
@@ -91,7 +96,12 @@ const Input = ({
case InputStepType.URL: case InputStepType.URL:
case InputStepType.PHONE: case InputStepType.PHONE:
return ( return (
<TextForm step={step} onSubmit={onSubmit} defaultValue={defaultValue} /> <TextForm
step={step}
onSubmit={onSubmit}
defaultValue={defaultValue}
hasGuestAvatar={hasGuestAvatar}
/>
) )
case InputStepType.DATE: case InputStepType.DATE:
return <DateForm options={step.options} onSubmit={onSubmit} /> return <DateForm options={step.options} onSubmit={onSubmit} />

View File

@@ -19,11 +19,19 @@ type TextFormProps = {
| PhoneNumberInputStep | PhoneNumberInputStep
onSubmit: (value: string) => void onSubmit: (value: string) => void
defaultValue?: string defaultValue?: string
hasGuestAvatar: boolean
} }
export const TextForm = ({ step, onSubmit, defaultValue }: TextFormProps) => { export const TextForm = ({
step,
onSubmit,
defaultValue,
hasGuestAvatar,
}: TextFormProps) => {
const [inputValue, setInputValue] = useState(defaultValue ?? '') const [inputValue, setInputValue] = useState(defaultValue ?? '')
const isLongText = step.type === InputStepType.TEXT && step.options?.isLong
const handleChange = (inputValue: string) => { const handleChange = (inputValue: string) => {
if (step.type === InputStepType.URL && !inputValue.startsWith('https://')) if (step.type === InputStepType.URL && !inputValue.startsWith('https://'))
return inputValue === 'https:/' return inputValue === 'https:/'
@@ -40,21 +48,21 @@ export const TextForm = ({ step, onSubmit, defaultValue }: TextFormProps) => {
} }
return ( return (
<div className="flex flex-col w-full lg:w-4/6 mb-2"> <form
<div className="flex items-center"> className="flex items-end justify-between rounded-lg pr-2 typebot-input w-full"
<form onSubmit={handleSubmit}
className="flex items-end justify-between rounded-lg pr-2 typebot-input" data-testid="input"
onSubmit={handleSubmit} style={{
data-testid="input" marginRight: hasGuestAvatar ? '50px' : '0.5rem',
> maxWidth: isLongText ? undefined : '350px',
<TextInput step={step} onChange={handleChange} value={inputValue} /> }}
<SendButton >
label={step.options?.labels?.button ?? 'Send'} <TextInput step={step} onChange={handleChange} value={inputValue} />
isDisabled={inputValue === ''} <SendButton
className="my-2 ml-2" label={step.options?.labels?.button ?? 'Send'}
/> isDisabled={inputValue === ''}
</form> className="my-2 ml-2"
</div> />
</div> </form>
) )
} }

View File

@@ -150,7 +150,7 @@ const LongTextInput = React.forwardRef(
<textarea <textarea
ref={ref} ref={ref}
className="focus:outline-none bg-transparent px-4 py-4 flex-1 w-full text-input" className="focus:outline-none bg-transparent px-4 py-4 flex-1 w-full text-input"
rows={4} rows={6}
data-testid="textarea" data-testid="textarea"
required required
style={{ fontSize: '16px' }} style={{ fontSize: '16px' }}