2
0

♻️ Simplify text bubble content shape

Remove html and plainText field because it was redundant

Closes #386
This commit is contained in:
Baptiste Arnaud
2023-04-13 17:04:21 +02:00
parent 2cbf8348c3
commit e0a9824913
70 changed files with 545 additions and 1030 deletions

View File

@ -1,10 +1,12 @@
import { TypingBubble } from '@/components'
import type { TextBubbleContent, TypingEmulation } from '@typebot.io/schemas'
import { createSignal, onCleanup, onMount } from 'solid-js'
import { computeTypingDuration } from '../utils/computeTypingDuration'
import { For, createSignal, onCleanup, onMount } from 'solid-js'
import { computeTypingDuration } from '../helpers/computeTypingDuration'
import { PlateBlock } from './plate/PlateBlock'
import { computePlainText } from '../helpers/convertRichTextToPlainText'
type Props = {
content: Pick<TextBubbleContent, 'html' | 'plainText'>
content: TextBubbleContent
typingEmulation: TypingEmulation
onTransitionEnd: () => void
}
@ -32,11 +34,12 @@ export const TextBubble = (props: Props) => {
onMount(() => {
if (!isTyping) return
const plainText = computePlainText(props.content.richText)
const typingDuration =
props.typingEmulation?.enabled === false
? 0
: computeTypingDuration(
props.content.plainText,
plainText,
props.typingEmulation ?? defaultTypingEmulation
)
typingTimeout = setTimeout(onTypingEnd, typingDuration)
@ -60,13 +63,16 @@ export const TextBubble = (props: Props) => {
>
{isTyping() && <TypingBubble />}
</div>
<p
<div
class={
'overflow-hidden text-fade-in mx-4 my-2 whitespace-pre-wrap slate-html-container relative text-ellipsis ' +
(isTyping() ? 'opacity-0 h-6' : 'opacity-100 h-full')
}
innerHTML={props.content.html}
/>
>
<For each={props.content.richText}>
{(element) => <PlateBlock element={element} />}
</For>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,30 @@
import type { TElement, TText, TDescendant } from '@udecode/plate-common'
import { PlateText, PlateTextProps } from './PlateText'
import { For, Match, Show, Switch } from 'solid-js'
type Props = { element: TElement | TText }
export const PlateBlock = (props: Props) => (
<Show
when={!props.element.text}
fallback={<PlateText {...(props.element as PlateTextProps)} />}
>
<Switch
fallback={
<div>
<For each={props.element.children as TDescendant[]}>
{(child) => <PlateBlock element={child} />}
</For>
</div>
}
>
<Match when={props.element.type === 'a'}>
<a href={props.element.url as string} target="_blank" class="slate-a">
<For each={props.element.children as TDescendant[]}>
{(child) => <PlateBlock element={child} />}
</For>
</a>
</Match>
</Switch>
</Show>
)

View File

@ -0,0 +1,30 @@
import { Show } from 'solid-js'
export type PlateTextProps = {
text: string
bold?: boolean
italic?: boolean
underline?: boolean
}
const computeClassNames = (
bold: boolean | undefined,
italic: boolean | undefined,
underline: boolean | undefined
) => {
let className = ''
if (bold) className += 'slate-bold'
if (italic) className += ' slate-italic'
if (underline) className += ' slate-underline'
return className
}
export const PlateText = (props: PlateTextProps) => (
<Show
when={computeClassNames(props.bold, props.italic, props.underline)}
keyed
fallback={<>{props.text}</>}
>
{(className) => <span class={className}>{props.text}</span>}
</Show>
)

View File

@ -0,0 +1,9 @@
import type { TDescendant } from '@udecode/plate-common'
export const computePlainText = (elements: TDescendant[]): string =>
elements
.map(
(element) =>
element.text ?? computePlainText(element.children as TDescendant[])
)
.join('')