UNPKG

tldraw

Version:

A tiny little drawing editor.

8 lines (7 loc) 6.29 kB
{ "version": 3, "sources": ["../../../../../src/lib/ui/components/Toolbar/DefaultImageToolbar.tsx"], "sourcesContent": ["import { Box, TLImageShape, useEditor, useValue } from '@tldraw/editor'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiContextualToolbar } from '../primitives/TldrawUiContextualToolbar'\nimport { AltTextEditor } from './AltTextEditor'\nimport { DefaultImageToolbarContent } from './DefaultImageToolbarContent'\n\n/** @public */\nexport interface TLUiImageToolbarProps {\n\tchildren?: React.ReactNode\n}\n\n/** @public @react */\nexport function DefaultImageToolbar({ children }: TLUiImageToolbarProps) {\n\tconst editor = useEditor()\n\tconst imageShapeId = useValue(\n\t\t'imageShape',\n\t\t() => {\n\t\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\t\tif (!onlySelectedShape || onlySelectedShape.type !== 'image') return null\n\t\t\treturn onlySelectedShape.id\n\t\t},\n\t\t[editor]\n\t)\n\tconst showToolbar = useValue(\n\t\t'showToolbar',\n\t\t() => editor.isInAny('select.idle', 'select.pointing_shape', 'select.crop'),\n\t\t[editor]\n\t)\n\tconst isLocked = useValue(\n\t\t'locked',\n\t\t() => (imageShapeId ? editor.getShape<TLImageShape>(imageShapeId)?.isLocked : false),\n\t\t[editor, imageShapeId]\n\t)\n\tif (!imageShapeId || !showToolbar || isLocked) return null\n\n\treturn (\n\t\t<ContextualToolbarInner key={imageShapeId} imageShapeId={imageShapeId}>\n\t\t\t{children}\n\t\t</ContextualToolbarInner>\n\t)\n}\n\nfunction ContextualToolbarInner({\n\tchildren,\n\timageShapeId,\n}: {\n\tchildren?: React.ReactNode\n\timageShapeId: TLImageShape['id']\n}) {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\n\tconst isChangingCrop = useValue(\n\t\t'editor path',\n\t\t() =>\n\t\t\teditor.isInAny(\n\t\t\t\t'select.crop.cropping',\n\t\t\t\t'select.crop.pointing_crop_handle',\n\t\t\t\t'select.crop.translating_crop'\n\t\t\t),\n\t\t[editor]\n\t)\n\tconst camera = useValue('camera', () => editor.getCamera(), [editor])\n\tconst isInCropTool = useValue('editor path', () => editor.isIn('select.crop.'), [editor])\n\tconst previousSelectionBounds = useRef<Box | undefined>(undefined)\n\tconst handleManipulatingEnd = useCallback(() => {\n\t\teditor.setCroppingShape(null)\n\t\teditor.setCurrentTool('select.idle')\n\t}, [editor])\n\n\tconst [isEditingAltText, setIsEditingAltText] = useState(false)\n\tconst handleEditAltTextStart = useCallback(() => setIsEditingAltText(true), [])\n\tconst handleManipulatingStart = useCallback(\n\t\t() => editor.setCurrentTool('select.crop.idle'),\n\t\t[editor]\n\t)\n\tconst onEditAltTextClose = useCallback(() => setIsEditingAltText(false), [])\n\n\tuseEffect(() => {\n\t\tpreviousSelectionBounds.current = undefined\n\t}, [camera])\n\n\tconst getSelectionBounds = useCallback(() => {\n\t\tif (isInCropTool && previousSelectionBounds.current) {\n\t\t\t// If we're cropping we want to be able to keep the toolbar in the same position.\n\t\t\treturn previousSelectionBounds.current\n\t\t}\n\t\tconst fullBounds = editor.getSelectionScreenBounds()\n\t\tif (!fullBounds) return undefined\n\t\tconst bounds = new Box(fullBounds.x, fullBounds.y, fullBounds.width, 0)\n\t\tpreviousSelectionBounds.current = bounds\n\t\treturn bounds\n\t}, [editor, isInCropTool])\n\n\tif (isChangingCrop) {\n\t\tpreviousSelectionBounds.current = undefined\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<TldrawUiContextualToolbar\n\t\t\tclassName=\"tlui-media__toolbar tlui-image__toolbar\"\n\t\t\tgetSelectionBounds={getSelectionBounds}\n\t\t\tlabel={msg('tool.image-toolbar-title')}\n\t\t>\n\t\t\t{children ? (\n\t\t\t\tchildren\n\t\t\t) : isEditingAltText ? (\n\t\t\t\t<AltTextEditor shapeId={imageShapeId} onClose={onEditAltTextClose} source=\"image-toolbar\" />\n\t\t\t) : (\n\t\t\t\t<DefaultImageToolbarContent\n\t\t\t\t\timageShapeId={imageShapeId}\n\t\t\t\t\tisManipulating={isInCropTool}\n\t\t\t\t\tonEditAltTextStart={handleEditAltTextStart}\n\t\t\t\t\tonManipulatingStart={handleManipulatingStart}\n\t\t\t\t\tonManipulatingEnd={handleManipulatingEnd}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</TldrawUiContextualToolbar>\n\t)\n}\n"], "mappings": "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", "names": [] }