tldraw
Version:
A tiny little drawing editor.
8 lines (7 loc) • 9.62 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../../src/lib/ui/components/EmbedDialog.tsx"],
"sourcesContent": ["import { track, useEditor } from '@tldraw/editor'\nimport { useRef, useState } from 'react'\nimport {\n\tTLEmbedDefinition,\n\tisCustomEmbedDefinition,\n\tisDefaultEmbedDefinitionType,\n} from '../../defaultEmbedDefinitions'\nimport { TLEmbedResult } from '../../utils/embeds/embeds'\nimport { useAssetUrls } from '../context/asset-urls'\nimport { TLUiDialogProps } from '../context/dialogs'\nimport { useGetEmbedDefinition } from '../hooks/useGetEmbedDefinition'\nimport { useGetEmbedDefinitions } from '../hooks/useGetEmbedDefinitions'\nimport { untranslated, useTranslation } from '../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from './primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonLabel } from './primitives/Button/TldrawUiButtonLabel'\nimport {\n\tTldrawUiDialogBody,\n\tTldrawUiDialogCloseButton,\n\tTldrawUiDialogFooter,\n\tTldrawUiDialogHeader,\n\tTldrawUiDialogTitle,\n} from './primitives/TldrawUiDialog'\nimport { TldrawUiInput } from './primitives/TldrawUiInput'\n\nexport const EmbedDialog = track(function EmbedDialog({ onClose }: TLUiDialogProps) {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\tconst assetUrls = useAssetUrls()\n\n\t// The embed definition for the user's selected embed (set by the user clicking on an embed in stage 1)\n\tconst [embedDefinition, setEmbedDefinition] = useState<null | TLEmbedDefinition>(null)\n\n\t// The URL that the user has typed into (in stage 2)\n\tconst [url, setUrl] = useState<string>('')\n\n\t// The embed info for the user's selected embed (based on the URL they've entered in stage 2)\n\tconst [embedInfoForUrl, setEmbedInfoForUrl] = useState<null | TLEmbedResult>(null)\n\n\t// Should we show the \"invalid URL\" error message?\n\tconst [showError, setShowError] = useState(false)\n\tconst rShowErrorTimeout = useRef<any>(-1)\n\n\tconst definitions = useGetEmbedDefinitions()\n\tconst getEmbedDefinition = useGetEmbedDefinition()\n\n\treturn (\n\t\t<>\n\t\t\t<TldrawUiDialogHeader>\n\t\t\t\t<TldrawUiDialogTitle>\n\t\t\t\t\t{embedDefinition\n\t\t\t\t\t\t? `${msg('embed-dialog.title')} \u2014 ${embedDefinition.title}`\n\t\t\t\t\t\t: msg('embed-dialog.title')}\n\t\t\t\t</TldrawUiDialogTitle>\n\t\t\t\t<TldrawUiDialogCloseButton />\n\t\t\t</TldrawUiDialogHeader>\n\t\t\t{embedDefinition ? (\n\t\t\t\t<>\n\t\t\t\t\t<TldrawUiDialogBody className=\"tlui-embed-dialog__enter\">\n\t\t\t\t\t\t<TldrawUiInput\n\t\t\t\t\t\t\tclassName=\"tlui-embed-dialog__input\"\n\t\t\t\t\t\t\tlabel=\"embed-dialog.url\"\n\t\t\t\t\t\t\tplaceholder=\"https://example.com\"\n\t\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\t\tonValueChange={(value) => {\n\t\t\t\t\t\t\t\t// Set the url that the user has typed into the input\n\t\t\t\t\t\t\t\tsetUrl(value)\n\n\t\t\t\t\t\t\t\t// Set the embed info to either the embed info for the URL (if\n\t\t\t\t\t\t\t\t// that embed info can be found and of a type that matches the\n\t\t\t\t\t\t\t\t// user's selected definition type)\n\t\t\t\t\t\t\t\tconst embedInfo = getEmbedDefinition(value)\n\t\t\t\t\t\t\t\tsetEmbedInfoForUrl(\n\t\t\t\t\t\t\t\t\tembedInfo && embedInfo.definition.type === embedDefinition.type ? embedInfo : null\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\t// We want to hide the error when the user enters text,\n\t\t\t\t\t\t\t\t// and then show an error after a short delay if the user\n\t\t\t\t\t\t\t\t// has not yet entered a valid URL.\n\t\t\t\t\t\t\t\tsetShowError(false)\n\t\t\t\t\t\t\t\tclearTimeout(rShowErrorTimeout.current)\n\n\t\t\t\t\t\t\t\trShowErrorTimeout.current = editor.timers.setTimeout(\n\t\t\t\t\t\t\t\t\t() => setShowError(!embedInfo),\n\t\t\t\t\t\t\t\t\t320\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{url === '' ? (\n\t\t\t\t\t\t\t<div className=\"tlui-embed-dialog__instruction\">\n\t\t\t\t\t\t\t\t<span>{msg('embed-dialog.instruction')}</span>{' '}\n\t\t\t\t\t\t\t\t{embedDefinition.instructionLink && (\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t\t\thref={embedDefinition.instructionLink}\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-embed-dialog__instruction__link\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\tLearn more\n\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t.\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<div className=\"tlui-embed-dialog__warning\">\n\t\t\t\t\t\t\t\t{showError ? msg('embed-dialog.invalid-url') : '\\xa0'}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</TldrawUiDialogBody>\n\t\t\t\t\t<TldrawUiDialogFooter className=\"tlui-dialog__footer__actions\">\n\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\ttype=\"normal\"\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tsetEmbedDefinition(null)\n\t\t\t\t\t\t\t\tsetEmbedInfoForUrl(null)\n\t\t\t\t\t\t\t\tsetUrl('')\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<TldrawUiButtonLabel>{msg('embed-dialog.back')}</TldrawUiButtonLabel>\n\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t<div className=\"tlui-embed__spacer\" />\n\t\t\t\t\t\t<TldrawUiButton type=\"normal\" onClick={onClose}>\n\t\t\t\t\t\t\t<TldrawUiButtonLabel>{msg('embed-dialog.cancel')}</TldrawUiButtonLabel>\n\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\ttype=\"primary\"\n\t\t\t\t\t\t\tdisabled={!embedInfoForUrl}\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tif (!embedInfoForUrl) return\n\n\t\t\t\t\t\t\t\teditor.putExternalContent({\n\t\t\t\t\t\t\t\t\ttype: 'embed',\n\t\t\t\t\t\t\t\t\turl,\n\t\t\t\t\t\t\t\t\tpoint: editor.getViewportPageBounds().center,\n\t\t\t\t\t\t\t\t\tembed: embedInfoForUrl.definition,\n\t\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\t\tonClose()\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<TldrawUiButtonLabel>{msg('embed-dialog.create')}</TldrawUiButtonLabel>\n\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t</TldrawUiDialogFooter>\n\t\t\t\t</>\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<TldrawUiDialogBody className=\"tlui-embed-dialog__list\">\n\t\t\t\t\t\t{definitions.map((def) => {\n\t\t\t\t\t\t\tconst url = isDefaultEmbedDefinitionType(def.type)\n\t\t\t\t\t\t\t\t? assetUrls.embedIcons[def.type]\n\t\t\t\t\t\t\t\t: isCustomEmbedDefinition(def)\n\t\t\t\t\t\t\t\t\t? def.icon\n\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<TldrawUiButton type=\"menu\" key={def.type} onClick={() => setEmbedDefinition(def)}>\n\t\t\t\t\t\t\t\t\t<TldrawUiButtonLabel>{untranslated(def.title)}</TldrawUiButtonLabel>\n\t\t\t\t\t\t\t\t\t{url && (\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-embed-dialog__item__image\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{ backgroundImage: `url(${url})` }}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t})}\n\t\t\t\t\t</TldrawUiDialogBody>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</>\n\t)\n})\n"],
"mappings": "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",
"names": ["EmbedDialog", "url"]
}