{
  "version": 3,
  "sources": ["../../../../src/lib/ui/components/EditLinkDialog.tsx"],
  "sourcesContent": ["import { defineMessages, T, TLShape, track, useEditor } from '@tldraw/editor'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { isShapeWithLink, TLShapeWithLink } from '../../utils/shapes/shapes'\nimport { TLUiDialogProps } from '../context/dialogs'\nimport { F } from '../context/i18n'\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\n// A url can either be invalid, or valid with a protocol, or valid without a protocol.\n// For example, \"aol.com\" would be valid with a protocol ()\nfunction validateUrl(url: string) {\n\tif (T.linkUrl.isValid(url)) {\n\t\treturn { isValid: true, hasProtocol: true }\n\t}\n\tif (T.linkUrl.isValid('https://' + url)) {\n\t\treturn { isValid: true, hasProtocol: false }\n\t}\n\treturn { isValid: false, hasProtocol: false }\n}\n\nfunction getUrlInputState(url: string) {\n\tconst { isValid, hasProtocol } = validateUrl(url)\n\tconst safe = isValid ? (hasProtocol ? url : 'https://' + url) : 'https://'\n\treturn { actual: url, safe, valid: isValid }\n}\n\nfunction assertShapeWithLink(shape: TLShape | null | undefined): asserts shape is TLShapeWithLink {\n\tif (!isShapeWithLink(shape)) {\n\t\tthrow new Error('Shape is not a valid TLShapeWithLink')\n\t}\n}\n\nconst messages = defineMessages({\n\t// `TldrawUiInput` takes its label as data, not as an element, so this one can't be an `<F>`.\n\turl: { id: 'edit-link-dialog.url', defaultMessage: 'URL' },\n})\n\nexport const EditLinkDialog = track(function EditLinkDialog({ onClose }: TLUiDialogProps) {\n\tconst editor = useEditor()\n\n\tconst selectedShape = editor.getOnlySelectedShape()\n\tconst hasShapeWithLink = isShapeWithLink(selectedShape)\n\n\t// The shape can be deleted or deselected from under the open dialog (a collaborator, or a\n\t// keypress reaching the canvas). Returning null on its own would leave an empty dialog frame.\n\tuseEffect(() => {\n\t\tif (!hasShapeWithLink) onClose()\n\t}, [hasShapeWithLink, onClose])\n\n\tif (!hasShapeWithLink) {\n\t\treturn null\n\t}\n\n\treturn <EditLinkDialogInner onClose={onClose} selectedShape={selectedShape} />\n})\n\nexport const EditLinkDialogInner = track(function EditLinkDialogInner({\n\tonClose,\n\tselectedShape,\n}: TLUiDialogProps & { selectedShape: TLShapeWithLink }) {\n\tconst editor = useEditor()\n\n\tconst rInput = useRef<HTMLInputElement>(null)\n\n\tuseEffect(() => {\n\t\teditor.timers.requestAnimationFrame(() => rInput.current?.focus())\n\t}, [editor])\n\n\tconst rInitialValue = useRef(selectedShape.props.url)\n\n\tconst [urlInputState, setUrlInputState] = useState(() => {\n\t\tconst { safe } = getUrlInputState(selectedShape.props.url)\n\t\treturn { actual: safe, safe, valid: true }\n\t})\n\n\tconst handleChange = useCallback((rawValue: string) => {\n\t\t// Just auto-correct double https:// from a bad paste.\n\t\tconst fixedRawValue = rawValue.replace(/https?:\\/\\/(https?:\\/\\/)/, '$1')\n\t\tsetUrlInputState(getUrlInputState(fixedRawValue))\n\t}, [])\n\n\tconst handleClear = useCallback(() => {\n\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\tif (!onlySelectedShape) return\n\t\tassertShapeWithLink(onlySelectedShape)\n\t\teditor.updateShapes([\n\t\t\t{ id: onlySelectedShape.id, type: onlySelectedShape.type, props: { url: '' } },\n\t\t])\n\t\tonClose()\n\t}, [editor, onClose])\n\n\tconst handleComplete = useCallback(() => {\n\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\n\t\tif (!onlySelectedShape) return\n\t\tassertShapeWithLink(onlySelectedShape)\n\n\t\t// Here would be a good place to validate the next shape\u2014would setting the empty\n\t\tif (onlySelectedShape.props.url !== urlInputState.safe) {\n\t\t\teditor.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid: onlySelectedShape.id,\n\t\t\t\t\ttype: onlySelectedShape.type,\n\t\t\t\t\tprops: { url: urlInputState.safe },\n\t\t\t\t},\n\t\t\t])\n\t\t}\n\t\tonClose()\n\t}, [editor, onClose, urlInputState])\n\n\tconst handleCancel = useCallback(() => {\n\t\tonClose()\n\t}, [onClose])\n\n\t// Are we going from a valid state to an invalid state?\n\tconst isRemoving = rInitialValue.current && !urlInputState.valid\n\n\treturn (\n\t\t<>\n\t\t\t<TldrawUiDialogHeader>\n\t\t\t\t<TldrawUiDialogTitle>\n\t\t\t\t\t<F defaultMessage=\"Edit link\" id=\"edit-link-dialog.title\" />\n\t\t\t\t</TldrawUiDialogTitle>\n\t\t\t\t<TldrawUiDialogCloseButton />\n\t\t\t</TldrawUiDialogHeader>\n\t\t\t<TldrawUiDialogBody>\n\t\t\t\t<div className=\"tlui-edit-link-dialog\">\n\t\t\t\t\t<TldrawUiInput\n\t\t\t\t\t\tref={rInput}\n\t\t\t\t\t\tclassName=\"tlui-edit-link-dialog__input\"\n\t\t\t\t\t\tlabel={messages.url.id}\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tautoSelect\n\t\t\t\t\t\tplaceholder=\"https://example.com\"\n\t\t\t\t\t\tvalue={urlInputState.actual}\n\t\t\t\t\t\tonValueChange={handleChange}\n\t\t\t\t\t\tonComplete={handleComplete}\n\t\t\t\t\t\tonCancel={handleCancel}\n\t\t\t\t\t/>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t{urlInputState.valid ? (\n\t\t\t\t\t\t\t<F defaultMessage=\"Links will open in a new tab.\" id=\"edit-link-dialog.detail\" />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<F defaultMessage=\"A link must be a valid URL.\" id=\"edit-link-dialog.invalid-url\" />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</TldrawUiDialogBody>\n\t\t\t<TldrawUiDialogFooter className=\"tlui-dialog__footer__actions\">\n\t\t\t\t<TldrawUiButton type=\"normal\" onClick={handleCancel} onTouchEnd={handleCancel}>\n\t\t\t\t\t<TldrawUiButtonLabel>\n\t\t\t\t\t\t<F defaultMessage=\"Cancel\" id=\"edit-link-dialog.cancel\" />\n\t\t\t\t\t</TldrawUiButtonLabel>\n\t\t\t\t</TldrawUiButton>\n\t\t\t\t{isRemoving ? (\n\t\t\t\t\t<TldrawUiButton type=\"danger\" onTouchEnd={handleClear} onClick={handleClear}>\n\t\t\t\t\t\t<TldrawUiButtonLabel>\n\t\t\t\t\t\t\t<F defaultMessage=\"Clear\" id=\"edit-link-dialog.clear\" />\n\t\t\t\t\t\t</TldrawUiButtonLabel>\n\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t) : (\n\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\ttype=\"primary\"\n\t\t\t\t\t\tdisabled={!urlInputState.valid}\n\t\t\t\t\t\tonTouchEnd={handleComplete}\n\t\t\t\t\t\tonClick={handleComplete}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TldrawUiButtonLabel>\n\t\t\t\t\t\t\t<F defaultMessage=\"Continue\" id=\"edit-link-dialog.save\" />\n\t\t\t\t\t\t</TldrawUiButtonLabel>\n\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t)}\n\t\t\t</TldrawUiDialogFooter>\n\t\t</>\n\t)\n})\n"],
  "mappings": "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",
  "names": ["EditLinkDialog", "EditLinkDialogInner"]
}
