Skip to content

Commit

Permalink
🚸 (textBubble) Allow mailto and tel links
Browse files Browse the repository at this point in the history
Closes #137
  • Loading branch information
baptisteArno committed Oct 22, 2022
1 parent 36a2fe3 commit baa63a7
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ export const BlockNode = ({

return isEditing && isTextBubbleBlock(block) ? (
<TextBubbleEditor
id={block.id}
initialValue={block.content.richText}
onClose={handleCloseEditor}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,40 @@
import { Flex, Stack, useOutsideClick } from '@chakra-ui/react'
import React, { useEffect, useMemo, useRef, useState } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import {
Plate,
PlateProvider,
selectEditor,
TEditor,
TElement,
Value,
withPlate,
usePlateEditorRef,
} from '@udecode/plate-core'
import { editorStyle, platePlugins } from 'libs/plate'
import { BaseEditor, BaseSelection, createEditor, Transforms } from 'slate'
import { BaseEditor, BaseSelection, Transforms } from 'slate'
import { ToolBar } from './ToolBar'
import { parseHtmlStringToPlainText } from 'services/utils'
import { defaultTextBubbleContent, TextBubbleContent, Variable } from 'models'
import { VariableSearchInput } from 'components/shared/VariableSearchInput'
import { ReactEditor } from 'slate-react'
import { serializeHtml } from '@udecode/plate-serializer-html'

type Props = {
initialValue: TElement[]
type TextBubbleEditorContentProps = {
id: string
textEditorValue: TElement[]
onClose: (newContent: TextBubbleContent) => void
}

export const TextBubbleEditor = ({ initialValue, onClose }: Props) => {
const randomEditorId = useMemo(() => Math.random().toString(), [])
const editor = useMemo(
() =>
withPlate(createEditor() as TEditor<Value>, {
id: randomEditorId,
plugins: platePlugins,
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
)
const [value, setValue] = useState(initialValue)
const TextBubbleEditorContent = ({
id,
textEditorValue,
onClose,
}: TextBubbleEditorContentProps) => {
const editor = usePlateEditorRef()
const varDropdownRef = useRef<HTMLDivElement | null>(null)
const rememberedSelection = useRef<BaseSelection | null>(null)
const [isVariableDropdownOpen, setIsVariableDropdownOpen] = useState(false)

const textEditorRef = useRef<HTMLDivElement>(null)

const closeEditor = () => onClose(convertValueToBlockContent(value))
const closeEditor = () => onClose(convertValueToBlockContent(textEditorValue))

useOutsideClick({
ref: textEditorRef,
Expand Down Expand Up @@ -94,10 +88,6 @@ export const TextBubbleEditor = ({ initialValue, onClose }: Props) => {
ReactEditor.focus(editor as unknown as ReactEditor)
}

const handleChangeEditorContent = (val: TElement[]) => {
setValue(val)
setIsVariableDropdownOpen(false)
}
const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
if (e.shiftKey) return
if (e.key === 'Enter') closeEditor()
Expand All @@ -115,12 +105,9 @@ export const TextBubbleEditor = ({ initialValue, onClose }: Props) => {
spacing={0}
cursor="text"
>
<ToolBar
editor={editor}
onVariablesButtonClick={() => setIsVariableDropdownOpen(true)}
/>
<ToolBar onVariablesButtonClick={() => setIsVariableDropdownOpen(true)} />
<Plate
id={randomEditorId}
id={id}
editableProps={{
style: editorStyle,
autoFocus: true,
Expand All @@ -136,13 +123,6 @@ export const TextBubbleEditor = ({ initialValue, onClose }: Props) => {
},
onKeyDown: handleKeyDown,
}}
initialValue={
initialValue.length === 0
? [{ type: 'p', children: [{ text: '' }] }]
: initialValue
}
onChange={handleChangeEditorContent}
editor={editor}
/>
{isVariableDropdownOpen && (
<Flex
Expand All @@ -164,3 +144,36 @@ export const TextBubbleEditor = ({ initialValue, onClose }: Props) => {
</Stack>
)
}

type TextBubbleEditorProps = {
id: string
initialValue: TElement[]
onClose: (newContent: TextBubbleContent) => void
}

export const TextBubbleEditor = ({
id,
initialValue,
onClose,
}: TextBubbleEditorProps) => {
const [textEditorValue, setTextEditorValue] = useState(initialValue)

return (
<PlateProvider
id={id}
plugins={platePlugins}
initialValue={
initialValue.length === 0
? [{ type: 'p', children: [{ text: '' }] }]
: initialValue
}
onChange={setTextEditorValue}
>
<TextBubbleEditorContent
id={id}
textEditorValue={textEditorValue}
onClose={onClose}
/>
</PlateProvider>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
MARK_ITALIC,
MARK_UNDERLINE,
} from '@udecode/plate-basic-marks'
import { getPluginType, PlateEditor, Value } from '@udecode/plate-core'
import { getPluginType, usePlateEditorRef } from '@udecode/plate-core'
import { LinkToolbarButton } from '@udecode/plate-ui-link'
import { MarkToolbarButton } from '@udecode/plate-ui-toolbar'
import {
Expand All @@ -16,15 +16,11 @@ import {
} from 'assets/icons'

type Props = {
editor: PlateEditor<Value>
onVariablesButtonClick: () => void
} & StackProps

export const ToolBar = ({
editor,
onVariablesButtonClick,
...props
}: Props) => {
export const ToolBar = ({ onVariablesButtonClick, ...props }: Props) => {
const editor = usePlateEditorRef()
const handleVariablesButtonMouseDown = (e: React.MouseEvent) => {
e.preventDefault()
onVariablesButtonClick()
Expand Down
7 changes: 7 additions & 0 deletions apps/builder/libs/plate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ export const platePlugins = createPlugins(
createUnderlinePlugin(),
createLinkPlugin({
renderAfterEditable: PlateFloatingLink,
options: {
isUrl: (url: string) =>
url.startsWith('http') ||
url.startsWith('mailto') ||
url.startsWith('tel') ||
url.startsWith('sms'),
},
}),
],
{
Expand Down
14 changes: 7 additions & 7 deletions apps/builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
"@sentry/nextjs": "7.15.0",
"@stripe/stripe-js": "1.41.0",
"@tanstack/react-table": "8.5.15",
"@udecode/plate-basic-marks": "16.8.0",
"@udecode/plate-basic-marks": "18.2.0",
"@udecode/plate-common": "^7.0.2",
"@udecode/plate-core": "16.8.0",
"@udecode/plate-link": "16.9.0",
"@udecode/plate-serializer-html": "16.8.0",
"@udecode/plate-ui-link": "16.9.0",
"@udecode/plate-ui-toolbar": "16.8.0",
"@udecode/plate-core": "18.2.0",
"@udecode/plate-link": "18.2.0",
"@udecode/plate-serializer-html": "18.2.0",
"@udecode/plate-ui-link": "18.2.0",
"@udecode/plate-ui-toolbar": "18.2.0",
"aws-sdk": "2.1233.0",
"bot-engine": "workspace:*",
"browser-image-compression": "2.0.0",
Expand Down Expand Up @@ -70,7 +70,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-draggable": "4.4.5",
"slate": "0.82.1",
"slate": "0.84.0",
"slate-history": "0.66.0",
"slate-hyperscript": "0.77.0",
"slate-react": "0.83.2",
Expand Down
Loading

5 comments on commit baa63a7

@vercel
Copy link

@vercel vercel bot commented on baa63a7 Oct 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on baa63a7 Oct 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

viewer-v2-alpha – ./apps/viewer

247987.com
8jours.top
bt.id8rs.com
ns8.vn
yobot.me
bot.aws.bj
minipost.uk
sat.cr8.ai
bot.aipr.kr
finplex.be
am.nigerias.io
an.nigerias.io
bot.enreso.org
bot.krdfy.com
bot.lalmon.com
vhpage.cr8.ai
apo.nigerias.io
ar.nigerias.io
ticketfute.com
apr.nigerias.io
aso.nigerias.io
bot.artiweb.app
bot.ageenda.com
bot.tc-mail.com
sakuranembro.it
games.klujo.com
chat.sureb4.com
eventhub.com.au
bot.piccinato.co
typebot.aloe.do
bot.upfunnel.art
botc.ceox.com.br
clo.closeer.work
faqs.nigerias.io
feedback.ofx.one
myrentalhost.com
form.syncwin.com
kw.wpwakanda.com
stan.vselise.com
typebot.aloe.bot
voicehelp.cr8.ai
app.chatforms.net
bot.agfunnel.tech
bot.hostnation.de
cares.urlabout.me
bot.reviewzer.com
bot.maitempah.com
bot.phuonghub.com
fmm.wpwakanda.com
gentleman-shop.fr
k1.kandabrand.com
lb.ticketfute.com
ov1.wpwakanda.com
ov3.wpwakanda.com
ov2.wpwakanda.com
andreimayer.com.br
bot.megafox.com.br
1988.bouclidom.com
bots.robomotion.io
bot.neferlopez.com
goalsettingbot.com
cadu.uninta.edu.br
dicanatural.online
this-is-a-test.com
bot.digitalbled.com
positivobra.com.br
carsalesenquiry.com
survey.digienge.io
zap.techadviser.in
bot.eventhub.com.au
demo.botscientis.us
forms.webisharp.com
kbsub.wpwakanda.com
mentoria.omelhor.vc
nutrisamirbayde.com
quest.wpwakanda.com
order.maitempah.com
test.botscientis.us
typebot.stillio.com
live.botscientis.us
bot.cotemeuplano.com
bium.gratirabbit.com
bot.ansuraniphone.my
chat.hayurihijab.com
chatbee.agfunnel.com
connect.growthguy.in
get.freebotoffer.xyz
offer.botscientis.us
kuiz.sistemniaga.com
click.sevenoways.com
talkbot.agfunnel.com
tenorioadvogados.com
uppity.wpwakanda.com
abutton.wpwakanda.com
aidigitalmarketing.kr
bbutton.wpwakanda.com
bot.ramonmatos.com.br
bot.incusservices.com
cdd.searchcube.com.sg
bot.meuesocial.com.br

@vercel
Copy link

@vercel vercel bot commented on baa63a7 Oct 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

docs – ./apps/docs

docs.typebot.io
docs-git-main-typebot-io.vercel.app
docs-typebot-io.vercel.app

@vercel
Copy link

@vercel vercel bot commented on baa63a7 Oct 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on baa63a7 Oct 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

builder-v2 – ./apps/builder

builder-v2-typebot-io.vercel.app
builder-v2-git-main-typebot-io.vercel.app
app.typebot.io

Please sign in to comment.