feat(engine): 💄 Better long text input
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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} />
|
||||||
|
|||||||
@@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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' }}
|
||||||
|
|||||||
Reference in New Issue
Block a user