tldraw 4.2.0-next.f100cedfc45b → 4.3.0-canary.071cf881c1c6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +3 -2
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/canvas/TldrawSelectionForeground.js +5 -2
- package/dist-cjs/lib/canvas/TldrawSelectionForeground.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js +63 -36
- package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js.map +2 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +3 -3
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/ShapeFill.js +3 -0
- package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +14 -6
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
- package/dist-cjs/lib/ui/components/Dialogs.js +2 -14
- package/dist-cjs/lib/ui/components/Dialogs.js.map +2 -2
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +5 -4
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.js +2 -1
- package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/Button/TldrawUiButton.js +2 -2
- package/dist-cjs/lib/ui/components/primitives/Button/TldrawUiButton.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +2 -1
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +16 -0
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/context/events.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +18 -16
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +3 -3
- package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +1 -0
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTranslation/useTranslation.js +1 -0
- package/dist-cjs/lib/ui/hooks/useTranslation/useTranslation.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-esm/index.d.mts +3 -2
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs +6 -2
- package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs +65 -38
- package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -5
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/ShapeFill.mjs +3 -0
- package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +14 -6
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Dialogs.mjs +2 -14
- package/dist-esm/lib/ui/components/Dialogs.mjs.map +2 -2
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +5 -5
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.mjs +2 -1
- package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/Button/TldrawUiButton.mjs +2 -2
- package/dist-esm/lib/ui/components/primitives/Button/TldrawUiButton.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +2 -1
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +16 -0
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/context/events.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +18 -16
- package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +3 -3
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +1 -0
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTranslation/useTranslation.mjs +1 -0
- package/dist-esm/lib/ui/hooks/useTranslation/useTranslation.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/package.json +3 -3
- package/src/lib/canvas/TldrawSelectionForeground.tsx +18 -2
- package/src/lib/shapes/frame/components/FrameLabelInput.tsx +48 -24
- package/src/lib/shapes/note/NoteShapeUtil.tsx +6 -5
- package/src/lib/shapes/shared/ShapeFill.tsx +3 -0
- package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +19 -8
- package/src/lib/tools/SelectTool/childStates/Idle.ts +2 -2
- package/src/lib/ui/components/Dialogs.tsx +2 -14
- package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +6 -5
- package/src/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.tsx +4 -1
- package/src/lib/ui/components/primitives/Button/TldrawUiButton.tsx +3 -2
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +1 -0
- package/src/lib/ui/context/actions.tsx +16 -0
- package/src/lib/ui/context/events.tsx +1 -0
- package/src/lib/ui/hooks/useClipboardEvents.ts +12 -9
- package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +1 -0
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +1 -0
- package/src/lib/ui/hooks/useTranslation/useTranslation.tsx +2 -1
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +4 -6
- package/src/test/TldrawEditor.test.tsx +74 -29
- package/src/test/customSnapping.test.tsx +185 -0
- package/tldraw.css +4 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/ui/components/PageMenu/DefaultPageMenu.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n\tPageRecordType,\n\tTLPageId,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\ttlenv,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { memo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { useUiEvents } from '../../context/events'\nimport { useMenuIsOpen } from '../../hooks/useMenuIsOpen'\nimport { useReadonly } from '../../hooks/useReadonly'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonCheck } from '../primitives/Button/TldrawUiButtonCheck'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiButtonLabel } from '../primitives/Button/TldrawUiButtonLabel'\nimport {\n\tTldrawUiPopover,\n\tTldrawUiPopoverContent,\n\tTldrawUiPopoverTrigger,\n} from '../primitives/TldrawUiPopover'\nimport { TldrawUiRow } from '../primitives/layout'\nimport { PageItemInput } from './PageItemInput'\nimport { PageItemSubmenu } from './PageItemSubmenu'\nimport { onMovePage } from './edit-pages-shared'\n\n/** @public @react */\nexport const DefaultPageMenu = memo(function DefaultPageMenu() {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\tconst msg = useTranslation()\n\tconst breakpoint = useBreakpoint()\n\n\tconst handleOpenChange = useCallback(() => setIsEditing(false), [])\n\n\tconst [isOpen, onOpenChange] = useMenuIsOpen('page-menu', handleOpenChange)\n\n\tconst ITEM_HEIGHT = 36\n\n\tconst rSortableContainer = useRef<HTMLDivElement>(null)\n\n\tconst pages = useValue('pages', () => editor.getPages(), [editor])\n\tconst currentPage = useValue('currentPage', () => editor.getCurrentPage(), [editor])\n\tconst currentPageId = useValue('currentPageId', () => editor.getCurrentPageId(), [editor])\n\n\t// When in readonly mode, we don't allow a user to edit the pages\n\tconst isReadonlyMode = useReadonly()\n\n\t// If the user has reached the max page count, we disable the \"add page\" button\n\tconst maxPageCountReached = useValue(\n\t\t'maxPageCountReached',\n\t\t() => editor.getPages().length >= editor.options.maxPages,\n\t\t[editor]\n\t)\n\n\tconst isCoarsePointer = useValue(\n\t\t'isCoarsePointer',\n\t\t() => editor.getInstanceState().isCoarsePointer,\n\t\t[editor]\n\t)\n\n\t// The component has an \"editing state\" that may be toggled to expose additional controls\n\tconst [isEditing, setIsEditing] = useState(false)\n\n\tuseEffect(\n\t\tfunction closePageMenuOnEnterPressAfterPressingEnterToConfirmRename() {\n\t\t\tfunction handleKeyDown() {\n\t\t\t\tif (isEditing) return\n\t\t\t\tif (document.activeElement === document.body) {\n\t\t\t\t\teditor.menus.clearOpenMenus()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdocument.addEventListener('keydown', handleKeyDown, { passive: true })\n\t\t\treturn () => {\n\t\t\t\tdocument.removeEventListener('keydown', handleKeyDown)\n\t\t\t}\n\t\t},\n\t\t[editor, isEditing]\n\t)\n\n\tconst toggleEditing = useCallback(() => {\n\t\tif (isReadonlyMode) return\n\t\tsetIsEditing((s) => !s)\n\t}, [isReadonlyMode])\n\n\tconst rMutables = useRef({\n\t\tisPointing: false,\n\t\tstatus: 'idle' as 'idle' | 'pointing' | 'dragging',\n\t\tpointing: null as { id: string; index: number } | null,\n\t\tstartY: 0,\n\t\tstartIndex: 0,\n\t\tdragIndex: 0,\n\t})\n\n\tconst [sortablePositionItems, setSortablePositionItems] = useState(\n\t\tObject.fromEntries(\n\t\t\tpages.map((page, i) => [page.id, { y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false }])\n\t\t)\n\t)\n\n\t// Update the sortable position items when the pages change\n\tuseLayoutEffect(() => {\n\t\tsetSortablePositionItems(\n\t\t\tObject.fromEntries(\n\t\t\t\tpages.map((page, i) => [page.id, { y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false }])\n\t\t\t)\n\t\t)\n\t}, [ITEM_HEIGHT, pages])\n\n\t// Scroll the current page into view when the menu opens / when current page changes\n\tuseEffect(() => {\n\t\tif (!isOpen) return\n\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\tconst elm = document.querySelector(`[data-pageid=\"${currentPageId}\"]`) as HTMLDivElement\n\n\t\t\tif (elm) {\n\t\t\t\telm.querySelector('button')?.focus()\n\n\t\t\t\tconst container = rSortableContainer.current\n\t\t\t\tif (!container) return\n\t\t\t\t// Scroll into view is slightly borked on iOS Safari\n\n\t\t\t\t// if top of less than top cuttoff, scroll into view at top\n\t\t\t\tconst elmTopPosition = elm.offsetTop\n\t\t\t\tconst containerScrollTopPosition = container.scrollTop\n\t\t\t\tif (elmTopPosition < containerScrollTopPosition) {\n\t\t\t\t\tcontainer.scrollTo({ top: elmTopPosition })\n\t\t\t\t}\n\t\t\t\t// if bottom position is greater than bottom cutoff, scroll into view at bottom\n\t\t\t\tconst elmBottomPosition = elmTopPosition + ITEM_HEIGHT\n\t\t\t\tconst containerScrollBottomPosition = container.scrollTop + container.offsetHeight\n\t\t\t\tif (elmBottomPosition > containerScrollBottomPosition) {\n\t\t\t\t\tcontainer.scrollTo({ top: elmBottomPosition - container.offsetHeight })\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}, [ITEM_HEIGHT, currentPageId, isOpen, editor])\n\n\tconst handlePointerDown = useCallback(\n\t\t(e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst { clientY, currentTarget } = e\n\t\t\tconst {\n\t\t\t\tdataset: { id, index },\n\t\t\t} = currentTarget\n\n\t\t\tif (!id || !index) return\n\n\t\t\tconst mut = rMutables.current\n\n\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\tmut.status = 'pointing'\n\t\t\tmut.pointing = { id, index: +index! }\n\t\t\tconst current = sortablePositionItems[id]\n\t\t\tconst dragY = current.y\n\n\t\t\tmut.startY = clientY\n\t\t\tmut.startIndex = Math.max(0, Math.min(Math.round(dragY / ITEM_HEIGHT), pages.length - 1))\n\t\t},\n\t\t[ITEM_HEIGHT, pages.length, sortablePositionItems]\n\t)\n\n\tconst handlePointerMove = useCallback(\n\t\t(e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst mut = rMutables.current\n\t\t\tif (mut.status === 'pointing') {\n\t\t\t\tconst { clientY } = e\n\t\t\t\tconst offset = clientY - mut.startY\n\t\t\t\tif (Math.abs(offset) > 5) {\n\t\t\t\t\tmut.status = 'dragging'\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (mut.status === 'dragging') {\n\t\t\t\tconst { clientY } = e\n\t\t\t\tconst offsetY = clientY - mut.startY\n\t\t\t\tconst current = sortablePositionItems[mut.pointing!.id]\n\n\t\t\t\tconst { startIndex, pointing } = mut\n\t\t\t\tconst dragY = current.y + offsetY\n\t\t\t\tconst dragIndex = Math.max(0, Math.min(Math.round(dragY / ITEM_HEIGHT), pages.length - 1))\n\n\t\t\t\tconst next = { ...sortablePositionItems }\n\t\t\t\tnext[pointing!.id] = {\n\t\t\t\t\ty: current.y,\n\t\t\t\t\toffsetY,\n\t\t\t\t\tisSelected: true,\n\t\t\t\t}\n\n\t\t\t\tif (dragIndex !== mut.dragIndex) {\n\t\t\t\t\tmut.dragIndex = dragIndex\n\n\t\t\t\t\tfor (let i = 0; i < pages.length; i++) {\n\t\t\t\t\t\tconst item = pages[i]\n\t\t\t\t\t\tif (item.id === mut.pointing!.id) {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet { y } = next[item.id]\n\n\t\t\t\t\t\tif (dragIndex === startIndex) {\n\t\t\t\t\t\t\ty = i * ITEM_HEIGHT\n\t\t\t\t\t\t} else if (dragIndex < startIndex) {\n\t\t\t\t\t\t\tif (dragIndex <= i && i < startIndex) {\n\t\t\t\t\t\t\t\ty = (i + 1) * ITEM_HEIGHT\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ty = i * ITEM_HEIGHT\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (dragIndex > startIndex) {\n\t\t\t\t\t\t\tif (dragIndex >= i && i > startIndex) {\n\t\t\t\t\t\t\t\ty = (i - 1) * ITEM_HEIGHT\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ty = i * ITEM_HEIGHT\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (y !== next[item.id].y) {\n\t\t\t\t\t\t\tnext[item.id] = { y, offsetY: 0, isSelected: true }\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsetSortablePositionItems(next)\n\t\t\t}\n\t\t},\n\t\t[ITEM_HEIGHT, pages, sortablePositionItems]\n\t)\n\n\tconst handlePointerUp = useCallback(\n\t\t(e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst mut = rMutables.current\n\n\t\t\tif (mut.status === 'dragging') {\n\t\t\t\tconst { id, index } = mut.pointing!\n\t\t\t\tonMovePage(editor, id as TLPageId, index, mut.dragIndex, trackEvent)\n\t\t\t}\n\n\t\t\treleasePointerCapture(e.currentTarget, e)\n\t\t\tmut.status = 'idle'\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst handleKeyDown = useCallback(\n\t\t(e: React.KeyboardEvent<HTMLButtonElement>) => {\n\t\t\tconst mut = rMutables.current\n\t\t\t// bail on escape\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tif (mut.status === 'dragging') {\n\t\t\t\t\tsetSortablePositionItems(\n\t\t\t\t\t\tObject.fromEntries(\n\t\t\t\t\t\t\tpages.map((page, i) => [\n\t\t\t\t\t\t\t\tpage.id,\n\t\t\t\t\t\t\t\t{ y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false },\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tmut.status = 'idle'\n\t\t\t}\n\t\t},\n\t\t[ITEM_HEIGHT, pages]\n\t)\n\n\tconst handleCreatePageClick = useCallback(() => {\n\t\tif (isReadonlyMode) return\n\n\t\teditor.run(() => {\n\t\t\teditor.markHistoryStoppingPoint('creating page')\n\t\t\tconst newPageId = PageRecordType.createId()\n\t\t\teditor.createPage({ name: msg('page-menu.new-page-initial-name'), id: newPageId })\n\t\t\teditor.setCurrentPage(newPageId)\n\n\t\t\tsetIsEditing(true)\n\n\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\tconst elm = document.querySelector(`[data-pageid=\"${newPageId}\"]`) as HTMLDivElement\n\n\t\t\t\tif (elm) {\n\t\t\t\t\telm.querySelector('button')?.focus()\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t\ttrackEvent('new-page', { source: 'page-menu' })\n\t}, [editor, msg, isReadonlyMode, trackEvent])\n\n\tconst changePage = useCallback(\n\t\t(id: TLPageId) => {\n\t\t\teditor.setCurrentPage(id)\n\t\t\ttrackEvent('change-page', { source: 'page-menu' })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst renamePage = useCallback(\n\t\t(id: TLPageId, name: string) => {\n\t\t\teditor.renamePage(id, name)\n\t\t\ttrackEvent('rename-page', { source: 'page-menu' })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\treturn (\n\t\t<TldrawUiPopover id=\"pages\" onOpenChange={onOpenChange} open={isOpen}>\n\t\t\t<TldrawUiPopoverTrigger data-testid=\"main.page-menu\">\n\t\t\t\t<TldrawUiButton\n\t\t\t\t\ttype=\"menu\"\n\t\t\t\t\ttitle={currentPage.name}\n\t\t\t\t\tdata-testid=\"page-menu.button\"\n\t\t\t\t\tclassName=\"tlui-page-menu__trigger\"\n\t\t\t\t>\n\t\t\t\t\t<div className=\"tlui-page-menu__name\">{currentPage.name}</div>\n\t\t\t\t\t<TldrawUiButtonIcon icon=\"chevron-down\" small />\n\t\t\t\t</TldrawUiButton>\n\t\t\t</TldrawUiPopoverTrigger>\n\t\t\t<TldrawUiPopoverContent\n\t\t\t\tside=\"bottom\"\n\t\t\t\talign=\"start\"\n\t\t\t\tsideOffset={0}\n\t\t\t\tdisableEscapeKeyDown={isEditing}\n\t\t\t>\n\t\t\t\t<div className=\"tlui-page-menu__wrapper\">\n\t\t\t\t\t<div className=\"tlui-page-menu__header\">\n\t\t\t\t\t\t<div className=\"tlui-page-menu__header__title\">{msg('page-menu.title')}</div>\n\t\t\t\t\t\t{!isReadonlyMode && (\n\t\t\t\t\t\t\t<TldrawUiRow>\n\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.edit\"\n\t\t\t\t\t\t\t\t\ttitle={msg(isEditing ? 'page-menu.edit-done' : 'page-menu.edit-start')}\n\t\t\t\t\t\t\t\t\tonClick={toggleEditing}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={isEditing ? 'check' : 'edit'} />\n\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.create\"\n\t\t\t\t\t\t\t\t\ttitle={msg(\n\t\t\t\t\t\t\t\t\t\tmaxPageCountReached\n\t\t\t\t\t\t\t\t\t\t\t? 'page-menu.max-page-count-reached'\n\t\t\t\t\t\t\t\t\t\t\t: 'page-menu.create-new-page'\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\tdisabled={maxPageCountReached}\n\t\t\t\t\t\t\t\t\tonClick={handleCreatePageClick}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon=\"plus\" />\n\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t</TldrawUiRow>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div\n\t\t\t\t\t\tdata-testid=\"page-menu.list\"\n\t\t\t\t\t\tclassName=\"tlui-page-menu__list tlui-menu__group\"\n\t\t\t\t\t\tstyle={{ height: ITEM_HEIGHT * pages.length + 4 }}\n\t\t\t\t\t\tref={rSortableContainer}\n\t\t\t\t\t>\n\t\t\t\t\t\t{pages.map((page, index) => {\n\t\t\t\t\t\t\tconst position = sortablePositionItems[page.id] ?? {\n\t\t\t\t\t\t\t\tposition: index * 40,\n\t\t\t\t\t\t\t\toffsetY: 0,\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn isEditing ? (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tkey={page.id + '_editing'}\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.item\"\n\t\t\t\t\t\t\t\t\tdata-pageid={page.id}\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-page_menu__item__sortable\"\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tzIndex: page.id === currentPage.id ? 888 : index,\n\t\t\t\t\t\t\t\t\t\ttransform: `translate(0px, ${position.y + position.offsetY}px)`,\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\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page_menu__item__sortable__handle\"\n\t\t\t\t\t\t\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\t\t\t\t\t\t\tonPointerUp={handlePointerUp}\n\t\t\t\t\t\t\t\t\t\tonPointerMove={handlePointerMove}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t\t\t\t\t\tdata-id={page.id}\n\t\t\t\t\t\t\t\t\t\tdata-index={index}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon=\"drag-handle-dots\" />\n\t\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t\t{breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM && isCoarsePointer ? (\n\t\t\t\t\t\t\t\t\t\t// sigh, this is a workaround for iOS Safari\n\t\t\t\t\t\t\t\t\t\t// because the device and the radix popover seem\n\t\t\t\t\t\t\t\t\t\t// to be fighting over scroll position. Nothing\n\t\t\t\t\t\t\t\t\t\t// else seems to work!\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\t\t\ttype=\"normal\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page-menu__item__button\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tconst name = window.prompt('Rename page', page.name)\n\t\t\t\t\t\t\t\t\t\t\t\tif (name && name !== page.name) {\n\t\t\t\t\t\t\t\t\t\t\t\t\trenamePage(page.id, name)\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tonDoubleClick={toggleEditing}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonCheck checked={page.id === currentPage.id} />\n\t\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonLabel>{page.name}</TldrawUiButtonLabel>\n\t\t\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t\t) : (\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-page_menu__item__sortable__title\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{ height: ITEM_HEIGHT }}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<PageItemInput\n\t\t\t\t\t\t\t\t\t\t\t\tid={page.id}\n\t\t\t\t\t\t\t\t\t\t\t\tname={page.name}\n\t\t\t\t\t\t\t\t\t\t\t\tisCurrentPage={page.id === currentPage.id}\n\t\t\t\t\t\t\t\t\t\t\t\tonComplete={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetIsEditing(false)\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\tonCancel={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetIsEditing(false)\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t{!isReadonlyMode && (\n\t\t\t\t\t\t\t\t\t\t<div className=\"tlui-page_menu__item__submenu\" data-isediting={isEditing}>\n\t\t\t\t\t\t\t\t\t\t\t<PageItemSubmenu index={index} item={page} listSize={pages.length} />\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tkey={page.id}\n\t\t\t\t\t\t\t\t\tdata-pageid={page.id}\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.item\"\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-page-menu__item\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\t\ttype=\"normal\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page-menu__item__button\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => changePage(page.id)}\n\t\t\t\t\t\t\t\t\t\tonDoubleClick={toggleEditing}\n\t\t\t\t\t\t\t\t\t\ttitle={msg('page-menu.go-to-page')}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\t\t\t\t\t\tif (e.key === 'Enter') {\n\t\t\t\t\t\t\t\t\t\t\t\tif (page.id === currentPage.id) {\n\t\t\t\t\t\t\t\t\t\t\t\t\ttoggleEditing()\n\t\t\t\t\t\t\t\t\t\t\t\t\teditor.markEventAsHandled(e)\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\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\t\t<TldrawUiButtonCheck checked={page.id === currentPage.id} />\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonLabel>{page.name}</TldrawUiButtonLabel>\n\t\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t\t{!isReadonlyMode && (\n\t\t\t\t\t\t\t\t\t\t<div className=\"tlui-page_menu__item__submenu\">\n\t\t\t\t\t\t\t\t\t\t\t<PageItemSubmenu\n\t\t\t\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t\t\t\t\titem={page}\n\t\t\t\t\t\t\t\t\t\t\t\tlistSize={pages.length}\n\t\t\t\t\t\t\t\t\t\t\t\tonRename={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (tlenv.isIos) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst name = window.prompt('Rename page', page.name)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (name && name !== page.name) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trenamePage(page.id, name)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetIsEditing(true)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (currentPageId !== page.id) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tchangePage(page.id)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</TldrawUiPopoverContent>\n\t\t</TldrawUiPopover>\n\t)\n})\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import {\n\tPageRecordType,\n\tTLPageId,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { memo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { useUiEvents } from '../../context/events'\nimport { useMenuIsOpen } from '../../hooks/useMenuIsOpen'\nimport { useReadonly } from '../../hooks/useReadonly'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonCheck } from '../primitives/Button/TldrawUiButtonCheck'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiButtonLabel } from '../primitives/Button/TldrawUiButtonLabel'\nimport {\n\tTldrawUiPopover,\n\tTldrawUiPopoverContent,\n\tTldrawUiPopoverTrigger,\n} from '../primitives/TldrawUiPopover'\nimport { TldrawUiRow } from '../primitives/layout'\nimport { PageItemInput } from './PageItemInput'\nimport { PageItemSubmenu } from './PageItemSubmenu'\nimport { onMovePage } from './edit-pages-shared'\n\n/** @public @react */\nexport const DefaultPageMenu = memo(function DefaultPageMenu() {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\tconst msg = useTranslation()\n\tconst breakpoint = useBreakpoint()\n\n\tconst handleOpenChange = useCallback(() => setIsEditing(false), [])\n\n\tconst [isOpen, onOpenChange] = useMenuIsOpen('page-menu', handleOpenChange)\n\n\tconst ITEM_HEIGHT = 36\n\n\tconst rSortableContainer = useRef<HTMLDivElement>(null)\n\n\tconst pages = useValue('pages', () => editor.getPages(), [editor])\n\tconst currentPage = useValue('currentPage', () => editor.getCurrentPage(), [editor])\n\tconst currentPageId = useValue('currentPageId', () => editor.getCurrentPageId(), [editor])\n\n\t// When in readonly mode, we don't allow a user to edit the pages\n\tconst isReadonlyMode = useReadonly()\n\n\t// If the user has reached the max page count, we disable the \"add page\" button\n\tconst maxPageCountReached = useValue(\n\t\t'maxPageCountReached',\n\t\t() => editor.getPages().length >= editor.options.maxPages,\n\t\t[editor]\n\t)\n\n\tconst isCoarsePointer = useValue(\n\t\t'isCoarsePointer',\n\t\t() => editor.getInstanceState().isCoarsePointer,\n\t\t[editor]\n\t)\n\n\t// The component has an \"editing state\" that may be toggled to expose additional controls\n\tconst [isEditing, setIsEditing] = useState(false)\n\n\tuseEffect(\n\t\tfunction closePageMenuOnEnterPressAfterPressingEnterToConfirmRename() {\n\t\t\tfunction handleKeyDown() {\n\t\t\t\tif (isEditing) return\n\t\t\t\tif (document.activeElement === document.body) {\n\t\t\t\t\teditor.menus.clearOpenMenus()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdocument.addEventListener('keydown', handleKeyDown, { passive: true })\n\t\t\treturn () => {\n\t\t\t\tdocument.removeEventListener('keydown', handleKeyDown)\n\t\t\t}\n\t\t},\n\t\t[editor, isEditing]\n\t)\n\n\tconst toggleEditing = useCallback(() => {\n\t\tif (isReadonlyMode) return\n\t\tsetIsEditing((s) => !s)\n\t}, [isReadonlyMode])\n\n\tconst rMutables = useRef({\n\t\tisPointing: false,\n\t\tstatus: 'idle' as 'idle' | 'pointing' | 'dragging',\n\t\tpointing: null as { id: string; index: number } | null,\n\t\tstartY: 0,\n\t\tstartIndex: 0,\n\t\tdragIndex: 0,\n\t})\n\n\tconst [sortablePositionItems, setSortablePositionItems] = useState(\n\t\tObject.fromEntries(\n\t\t\tpages.map((page, i) => [page.id, { y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false }])\n\t\t)\n\t)\n\n\t// Update the sortable position items when the pages change\n\tuseLayoutEffect(() => {\n\t\tsetSortablePositionItems(\n\t\t\tObject.fromEntries(\n\t\t\t\tpages.map((page, i) => [page.id, { y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false }])\n\t\t\t)\n\t\t)\n\t}, [ITEM_HEIGHT, pages])\n\n\t// Scroll the current page into view when the menu opens / when current page changes\n\tuseEffect(() => {\n\t\tif (!isOpen) return\n\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\tconst elm = document.querySelector(`[data-pageid=\"${currentPageId}\"]`) as HTMLDivElement\n\n\t\t\tif (elm) {\n\t\t\t\telm.querySelector('button')?.focus()\n\n\t\t\t\tconst container = rSortableContainer.current\n\t\t\t\tif (!container) return\n\t\t\t\t// Scroll into view is slightly borked on iOS Safari\n\n\t\t\t\t// if top of less than top cuttoff, scroll into view at top\n\t\t\t\tconst elmTopPosition = elm.offsetTop\n\t\t\t\tconst containerScrollTopPosition = container.scrollTop\n\t\t\t\tif (elmTopPosition < containerScrollTopPosition) {\n\t\t\t\t\tcontainer.scrollTo({ top: elmTopPosition })\n\t\t\t\t}\n\t\t\t\t// if bottom position is greater than bottom cutoff, scroll into view at bottom\n\t\t\t\tconst elmBottomPosition = elmTopPosition + ITEM_HEIGHT\n\t\t\t\tconst containerScrollBottomPosition = container.scrollTop + container.offsetHeight\n\t\t\t\tif (elmBottomPosition > containerScrollBottomPosition) {\n\t\t\t\t\tcontainer.scrollTo({ top: elmBottomPosition - container.offsetHeight })\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}, [ITEM_HEIGHT, currentPageId, isOpen, editor])\n\n\tconst handlePointerDown = useCallback(\n\t\t(e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst { clientY, currentTarget } = e\n\t\t\tconst {\n\t\t\t\tdataset: { id, index },\n\t\t\t} = currentTarget\n\n\t\t\tif (!id || !index) return\n\n\t\t\tconst mut = rMutables.current\n\n\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\tmut.status = 'pointing'\n\t\t\tmut.pointing = { id, index: +index! }\n\t\t\tconst current = sortablePositionItems[id]\n\t\t\tconst dragY = current.y\n\n\t\t\tmut.startY = clientY\n\t\t\tmut.startIndex = Math.max(0, Math.min(Math.round(dragY / ITEM_HEIGHT), pages.length - 1))\n\t\t},\n\t\t[ITEM_HEIGHT, pages.length, sortablePositionItems]\n\t)\n\n\tconst handlePointerMove = useCallback(\n\t\t(e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst mut = rMutables.current\n\t\t\tif (mut.status === 'pointing') {\n\t\t\t\tconst { clientY } = e\n\t\t\t\tconst offset = clientY - mut.startY\n\t\t\t\tif (Math.abs(offset) > 5) {\n\t\t\t\t\tmut.status = 'dragging'\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (mut.status === 'dragging') {\n\t\t\t\tconst { clientY } = e\n\t\t\t\tconst offsetY = clientY - mut.startY\n\t\t\t\tconst current = sortablePositionItems[mut.pointing!.id]\n\n\t\t\t\tconst { startIndex, pointing } = mut\n\t\t\t\tconst dragY = current.y + offsetY\n\t\t\t\tconst dragIndex = Math.max(0, Math.min(Math.round(dragY / ITEM_HEIGHT), pages.length - 1))\n\n\t\t\t\tconst next = { ...sortablePositionItems }\n\t\t\t\tnext[pointing!.id] = {\n\t\t\t\t\ty: current.y,\n\t\t\t\t\toffsetY,\n\t\t\t\t\tisSelected: true,\n\t\t\t\t}\n\n\t\t\t\tif (dragIndex !== mut.dragIndex) {\n\t\t\t\t\tmut.dragIndex = dragIndex\n\n\t\t\t\t\tfor (let i = 0; i < pages.length; i++) {\n\t\t\t\t\t\tconst item = pages[i]\n\t\t\t\t\t\tif (item.id === mut.pointing!.id) {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet { y } = next[item.id]\n\n\t\t\t\t\t\tif (dragIndex === startIndex) {\n\t\t\t\t\t\t\ty = i * ITEM_HEIGHT\n\t\t\t\t\t\t} else if (dragIndex < startIndex) {\n\t\t\t\t\t\t\tif (dragIndex <= i && i < startIndex) {\n\t\t\t\t\t\t\t\ty = (i + 1) * ITEM_HEIGHT\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ty = i * ITEM_HEIGHT\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (dragIndex > startIndex) {\n\t\t\t\t\t\t\tif (dragIndex >= i && i > startIndex) {\n\t\t\t\t\t\t\t\ty = (i - 1) * ITEM_HEIGHT\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ty = i * ITEM_HEIGHT\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (y !== next[item.id].y) {\n\t\t\t\t\t\t\tnext[item.id] = { y, offsetY: 0, isSelected: true }\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsetSortablePositionItems(next)\n\t\t\t}\n\t\t},\n\t\t[ITEM_HEIGHT, pages, sortablePositionItems]\n\t)\n\n\tconst handlePointerUp = useCallback(\n\t\t(e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst mut = rMutables.current\n\n\t\t\tif (mut.status === 'dragging') {\n\t\t\t\tconst { id, index } = mut.pointing!\n\t\t\t\tonMovePage(editor, id as TLPageId, index, mut.dragIndex, trackEvent)\n\t\t\t}\n\n\t\t\treleasePointerCapture(e.currentTarget, e)\n\t\t\tmut.status = 'idle'\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst handleKeyDown = useCallback(\n\t\t(e: React.KeyboardEvent<HTMLButtonElement>) => {\n\t\t\tconst mut = rMutables.current\n\t\t\t// bail on escape\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tif (mut.status === 'dragging') {\n\t\t\t\t\tsetSortablePositionItems(\n\t\t\t\t\t\tObject.fromEntries(\n\t\t\t\t\t\t\tpages.map((page, i) => [\n\t\t\t\t\t\t\t\tpage.id,\n\t\t\t\t\t\t\t\t{ y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false },\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tmut.status = 'idle'\n\t\t\t}\n\t\t},\n\t\t[ITEM_HEIGHT, pages]\n\t)\n\n\tconst handleCreatePageClick = useCallback(() => {\n\t\tif (isReadonlyMode) return\n\n\t\teditor.run(() => {\n\t\t\teditor.markHistoryStoppingPoint('creating page')\n\t\t\tconst newPageId = PageRecordType.createId()\n\t\t\teditor.createPage({ name: msg('page-menu.new-page-initial-name'), id: newPageId })\n\t\t\teditor.setCurrentPage(newPageId)\n\n\t\t\tsetIsEditing(true)\n\n\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\tconst elm = document.querySelector(`[data-pageid=\"${newPageId}\"]`) as HTMLDivElement\n\n\t\t\t\tif (elm) {\n\t\t\t\t\telm.querySelector('button')?.focus()\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t\ttrackEvent('new-page', { source: 'page-menu' })\n\t}, [editor, msg, isReadonlyMode, trackEvent])\n\n\tconst changePage = useCallback(\n\t\t(id: TLPageId) => {\n\t\t\teditor.setCurrentPage(id)\n\t\t\ttrackEvent('change-page', { source: 'page-menu' })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst renamePage = useCallback(\n\t\t(id: TLPageId, name: string) => {\n\t\t\teditor.renamePage(id, name)\n\t\t\ttrackEvent('rename-page', { source: 'page-menu' })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst shouldUseWindowPrompt = breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM && isCoarsePointer\n\n\treturn (\n\t\t<TldrawUiPopover id=\"pages\" onOpenChange={onOpenChange} open={isOpen}>\n\t\t\t<TldrawUiPopoverTrigger data-testid=\"main.page-menu\">\n\t\t\t\t<TldrawUiButton\n\t\t\t\t\ttype=\"menu\"\n\t\t\t\t\ttitle={currentPage.name}\n\t\t\t\t\tdata-testid=\"page-menu.button\"\n\t\t\t\t\tclassName=\"tlui-page-menu__trigger\"\n\t\t\t\t>\n\t\t\t\t\t<div className=\"tlui-page-menu__name\">{currentPage.name}</div>\n\t\t\t\t\t<TldrawUiButtonIcon icon=\"chevron-down\" small />\n\t\t\t\t</TldrawUiButton>\n\t\t\t</TldrawUiPopoverTrigger>\n\t\t\t<TldrawUiPopoverContent\n\t\t\t\tside=\"bottom\"\n\t\t\t\talign=\"start\"\n\t\t\t\tsideOffset={0}\n\t\t\t\tdisableEscapeKeyDown={isEditing}\n\t\t\t>\n\t\t\t\t<div className=\"tlui-page-menu__wrapper\">\n\t\t\t\t\t<div className=\"tlui-page-menu__header\">\n\t\t\t\t\t\t<div className=\"tlui-page-menu__header__title\">{msg('page-menu.title')}</div>\n\t\t\t\t\t\t{!isReadonlyMode && (\n\t\t\t\t\t\t\t<TldrawUiRow>\n\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.edit\"\n\t\t\t\t\t\t\t\t\ttitle={msg(isEditing ? 'page-menu.edit-done' : 'page-menu.edit-start')}\n\t\t\t\t\t\t\t\t\tonClick={toggleEditing}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={isEditing ? 'check' : 'edit'} />\n\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.create\"\n\t\t\t\t\t\t\t\t\ttitle={msg(\n\t\t\t\t\t\t\t\t\t\tmaxPageCountReached\n\t\t\t\t\t\t\t\t\t\t\t? 'page-menu.max-page-count-reached'\n\t\t\t\t\t\t\t\t\t\t\t: 'page-menu.create-new-page'\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\tdisabled={maxPageCountReached}\n\t\t\t\t\t\t\t\t\tonClick={handleCreatePageClick}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon=\"plus\" />\n\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t</TldrawUiRow>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div\n\t\t\t\t\t\tdata-testid=\"page-menu.list\"\n\t\t\t\t\t\tclassName=\"tlui-page-menu__list tlui-menu__group\"\n\t\t\t\t\t\tstyle={{ height: ITEM_HEIGHT * pages.length + 4 }}\n\t\t\t\t\t\tref={rSortableContainer}\n\t\t\t\t\t>\n\t\t\t\t\t\t{pages.map((page, index) => {\n\t\t\t\t\t\t\tconst position = sortablePositionItems[page.id] ?? {\n\t\t\t\t\t\t\t\tposition: index * 40,\n\t\t\t\t\t\t\t\toffsetY: 0,\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn isEditing ? (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tkey={page.id + '_editing'}\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.item\"\n\t\t\t\t\t\t\t\t\tdata-pageid={page.id}\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-page_menu__item__sortable\"\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tzIndex: page.id === currentPage.id ? 888 : index,\n\t\t\t\t\t\t\t\t\t\ttransform: `translate(0px, ${position.y + position.offsetY}px)`,\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\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page_menu__item__sortable__handle\"\n\t\t\t\t\t\t\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\t\t\t\t\t\t\tonPointerUp={handlePointerUp}\n\t\t\t\t\t\t\t\t\t\tonPointerMove={handlePointerMove}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t\t\t\t\t\tdata-id={page.id}\n\t\t\t\t\t\t\t\t\t\tdata-index={index}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon=\"drag-handle-dots\" />\n\t\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t\t{shouldUseWindowPrompt ? (\n\t\t\t\t\t\t\t\t\t\t// sigh, this is a workaround for iOS Safari\n\t\t\t\t\t\t\t\t\t\t// because the device and the radix popover seem\n\t\t\t\t\t\t\t\t\t\t// to be fighting over scroll position. Nothing\n\t\t\t\t\t\t\t\t\t\t// else seems to work!\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\t\t\ttype=\"normal\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page-menu__item__button\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tconst name = window.prompt(msg('action.rename'), page.name)\n\t\t\t\t\t\t\t\t\t\t\t\tif (name && name !== page.name) {\n\t\t\t\t\t\t\t\t\t\t\t\t\trenamePage(page.id, name)\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tonDoubleClick={toggleEditing}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonCheck checked={page.id === currentPage.id} />\n\t\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonLabel>{page.name}</TldrawUiButtonLabel>\n\t\t\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t\t) : (\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-page_menu__item__sortable__title\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{ height: ITEM_HEIGHT }}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<PageItemInput\n\t\t\t\t\t\t\t\t\t\t\t\tid={page.id}\n\t\t\t\t\t\t\t\t\t\t\t\tname={page.name}\n\t\t\t\t\t\t\t\t\t\t\t\tisCurrentPage={page.id === currentPage.id}\n\t\t\t\t\t\t\t\t\t\t\t\tonComplete={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetIsEditing(false)\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\tonCancel={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetIsEditing(false)\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t{!isReadonlyMode && (\n\t\t\t\t\t\t\t\t\t\t<div className=\"tlui-page_menu__item__submenu\" data-isediting={isEditing}>\n\t\t\t\t\t\t\t\t\t\t\t<PageItemSubmenu index={index} item={page} listSize={pages.length} />\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tkey={page.id}\n\t\t\t\t\t\t\t\t\tdata-pageid={page.id}\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.item\"\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-page-menu__item\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\t\ttype=\"normal\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page-menu__item__button\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => changePage(page.id)}\n\t\t\t\t\t\t\t\t\t\tonDoubleClick={toggleEditing}\n\t\t\t\t\t\t\t\t\t\ttitle={msg('page-menu.go-to-page')}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\t\t\t\t\t\tif (e.key === 'Enter') {\n\t\t\t\t\t\t\t\t\t\t\t\tif (page.id === currentPage.id) {\n\t\t\t\t\t\t\t\t\t\t\t\t\ttoggleEditing()\n\t\t\t\t\t\t\t\t\t\t\t\t\teditor.markEventAsHandled(e)\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\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\t\t<TldrawUiButtonCheck checked={page.id === currentPage.id} />\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonLabel>{page.name}</TldrawUiButtonLabel>\n\t\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t\t{!isReadonlyMode && (\n\t\t\t\t\t\t\t\t\t\t<div className=\"tlui-page_menu__item__submenu\">\n\t\t\t\t\t\t\t\t\t\t\t<PageItemSubmenu\n\t\t\t\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t\t\t\t\titem={page}\n\t\t\t\t\t\t\t\t\t\t\t\tlistSize={pages.length}\n\t\t\t\t\t\t\t\t\t\t\t\tonRename={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (shouldUseWindowPrompt) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst name = window.prompt(msg('action.rename'), page.name)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (name && name !== page.name) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trenamePage(page.id, name)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetIsEditing(true)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (currentPageId !== page.id) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tchangePage(page.id)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</TldrawUiPopoverContent>\n\t\t</TldrawUiPopover>\n\t)\n})\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["DefaultPageMenu", "handleKeyDown"]
|
|
7
7
|
}
|
|
@@ -60,6 +60,7 @@ function DefaultRichTextToolbarContent({
|
|
|
60
60
|
}, [onEditLinkStart]);
|
|
61
61
|
const actions = (0, import_react.useMemo)(() => {
|
|
62
62
|
function handleOp(name, op) {
|
|
63
|
+
if (!textEditor.view) return;
|
|
63
64
|
trackEvent("rich-text", { operation: name, source });
|
|
64
65
|
textEditor.chain().focus()[op]().run();
|
|
65
66
|
}
|
|
@@ -107,7 +108,7 @@ function DefaultRichTextToolbarContent({
|
|
|
107
108
|
].filter(Boolean);
|
|
108
109
|
}, [textEditor, trackEvent, onEditLinkStart]);
|
|
109
110
|
return actions.map(({ name, attrs, onSelect }) => {
|
|
110
|
-
const isActive = textEditor.isActive(name, attrs);
|
|
111
|
+
const isActive = textEditor.view ? textEditor.isActive(name, attrs) : false;
|
|
111
112
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
112
113
|
import_TldrawUiToolbar.TldrawUiToolbarButton,
|
|
113
114
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.tsx"],
|
|
4
|
-
"sourcesContent": ["import { isAccelKey, preventDefault, TiptapEditor } from '@tldraw/editor'\nimport { useEffect, useMemo, useState } from 'react'\nimport { useUiEvents } from '../../context/events'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'\n\n/** @public */\nexport interface DefaultRichTextToolbarContentProps {\n\tonEditLinkStart?(): void\n\ttextEditor: TiptapEditor\n}\n\n/**\n * Rich text toolbar items that have the basics.\n *\n * @public @react\n */\nexport function DefaultRichTextToolbarContent({\n\ttextEditor,\n\tonEditLinkStart,\n}: DefaultRichTextToolbarContentProps) {\n\tconst trackEvent = useUiEvents()\n\tconst msg = useTranslation()\n\tconst source = 'rich-text-menu'\n\n\t// We need to force this one to update when the editor updates or when selection changes\n\tconst [_, set] = useState(0)\n\tuseEffect(\n\t\tfunction forceUpdateWhenContentChanges() {\n\t\t\tfunction forceUpdate() {\n\t\t\t\tset((t) => t + 1)\n\t\t\t}\n\t\t\ttextEditor.on('update', forceUpdate)\n\t\t\ttextEditor.on('selectionUpdate', forceUpdate)\n\t\t},\n\t\t[textEditor]\n\t)\n\n\tuseEffect(() => {\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (onEditLinkStart && isAccelKey(event) && event.shiftKey && event.key === 'k') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tonEditLinkStart()\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener('keydown', handleKeyDown)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('keydown', handleKeyDown)\n\t\t}\n\t}, [onEditLinkStart])\n\n\t// todo: we could make this a prop\n\tconst actions = useMemo(() => {\n\t\tfunction handleOp(name: string, op: string) {\n\t\t\ttrackEvent('rich-text', { operation: name as any, source })\n\t\t\t// @ts-expect-error typing this is annoying at the moment.\n\t\t\ttextEditor.chain().focus()[op]().run()\n\t\t}\n\n\t\treturn [\n\t\t\t// { name: 'heading', attrs: { level: 3 }, onSelect() { textEditor.chain().focus().toggleHeading({ level: 3}).run() }},\n\t\t\t{\n\t\t\t\tname: 'bold',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleBold')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'italic',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleItalic')\n\t\t\t\t},\n\t\t\t},\n\t\t\t// { name: 'underline', onSelect() { handleOp('underline', 'toggleUnderline') }},\n\t\t\t// { name: 'strike', onSelect() { handleOp('strike', 'toggleStrike') }},\n\t\t\t{\n\t\t\t\tname: 'code',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleCode')\n\t\t\t\t},\n\t\t\t},\n\t\t\tonEditLinkStart\n\t\t\t\t? {\n\t\t\t\t\t\tname: 'link',\n\t\t\t\t\t\tonSelect() {\n\t\t\t\t\t\t\tonEditLinkStart()\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: undefined, // ? is this really optional?\n\t\t\t{\n\t\t\t\tname: 'bulletList',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bulletList', 'toggleBulletList')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'highlight',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bulletList', 'toggleHighlight')\n\t\t\t\t},\n\t\t\t},\n\t\t].filter(Boolean) as {\n\t\t\tname: string\n\t\t\tattrs?: string\n\t\t\tonSelect(): void\n\t\t}[]\n\t}, [textEditor, trackEvent, onEditLinkStart])\n\n\treturn actions.map(({ name, attrs, onSelect }) => {\n\t\tconst isActive = textEditor.isActive(name, attrs)\n\t\treturn (\n\t\t\t<TldrawUiToolbarButton\n\t\t\t\tkey={name}\n\t\t\t\ttitle={msg(`tool.rich-text-${name}`)}\n\t\t\t\tdata-testid={`rich-text.${name}`}\n\t\t\t\ttype=\"icon\"\n\t\t\t\tisActive={isActive} // todo: we need to update this only when the text editor \"settles\", ie not during a change of selection\n\t\t\t\tonPointerDown={preventDefault}\n\t\t\t\tonClick={onSelect}\n\t\t\t\trole=\"option\"\n\t\t\t\taria-pressed={isActive}\n\t\t\t>\n\t\t\t\t<TldrawUiButtonIcon small icon={name} />\n\t\t\t</TldrawUiToolbarButton>\n\t\t)\n\t})\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import { isAccelKey, preventDefault, TiptapEditor } from '@tldraw/editor'\nimport { useEffect, useMemo, useState } from 'react'\nimport { useUiEvents } from '../../context/events'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'\n\n/** @public */\nexport interface DefaultRichTextToolbarContentProps {\n\tonEditLinkStart?(): void\n\ttextEditor: TiptapEditor\n}\n\n/**\n * Rich text toolbar items that have the basics.\n *\n * @public @react\n */\nexport function DefaultRichTextToolbarContent({\n\ttextEditor,\n\tonEditLinkStart,\n}: DefaultRichTextToolbarContentProps) {\n\tconst trackEvent = useUiEvents()\n\tconst msg = useTranslation()\n\tconst source = 'rich-text-menu'\n\n\t// We need to force this one to update when the editor updates or when selection changes\n\tconst [_, set] = useState(0)\n\tuseEffect(\n\t\tfunction forceUpdateWhenContentChanges() {\n\t\t\tfunction forceUpdate() {\n\t\t\t\tset((t) => t + 1)\n\t\t\t}\n\t\t\ttextEditor.on('update', forceUpdate)\n\t\t\ttextEditor.on('selectionUpdate', forceUpdate)\n\t\t},\n\t\t[textEditor]\n\t)\n\n\tuseEffect(() => {\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (onEditLinkStart && isAccelKey(event) && event.shiftKey && event.key === 'k') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tonEditLinkStart()\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener('keydown', handleKeyDown)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('keydown', handleKeyDown)\n\t\t}\n\t}, [onEditLinkStart])\n\n\t// todo: we could make this a prop\n\tconst actions = useMemo(() => {\n\t\tfunction handleOp(name: string, op: string) {\n\t\t\t// Check if the editor view is available before calling operations\n\t\t\tif (!textEditor.view) return\n\n\t\t\ttrackEvent('rich-text', { operation: name as any, source })\n\t\t\t// @ts-expect-error typing this is annoying at the moment.\n\t\t\ttextEditor.chain().focus()[op]().run()\n\t\t}\n\n\t\treturn [\n\t\t\t// { name: 'heading', attrs: { level: 3 }, onSelect() { textEditor.chain().focus().toggleHeading({ level: 3}).run() }},\n\t\t\t{\n\t\t\t\tname: 'bold',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleBold')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'italic',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleItalic')\n\t\t\t\t},\n\t\t\t},\n\t\t\t// { name: 'underline', onSelect() { handleOp('underline', 'toggleUnderline') }},\n\t\t\t// { name: 'strike', onSelect() { handleOp('strike', 'toggleStrike') }},\n\t\t\t{\n\t\t\t\tname: 'code',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleCode')\n\t\t\t\t},\n\t\t\t},\n\t\t\tonEditLinkStart\n\t\t\t\t? {\n\t\t\t\t\t\tname: 'link',\n\t\t\t\t\t\tonSelect() {\n\t\t\t\t\t\t\tonEditLinkStart()\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: undefined, // ? is this really optional?\n\t\t\t{\n\t\t\t\tname: 'bulletList',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bulletList', 'toggleBulletList')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'highlight',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bulletList', 'toggleHighlight')\n\t\t\t\t},\n\t\t\t},\n\t\t].filter(Boolean) as {\n\t\t\tname: string\n\t\t\tattrs?: string\n\t\t\tonSelect(): void\n\t\t}[]\n\t}, [textEditor, trackEvent, onEditLinkStart])\n\n\treturn actions.map(({ name, attrs, onSelect }) => {\n\t\tconst isActive = textEditor.view ? textEditor.isActive(name, attrs) : false\n\t\treturn (\n\t\t\t<TldrawUiToolbarButton\n\t\t\t\tkey={name}\n\t\t\t\ttitle={msg(`tool.rich-text-${name}`)}\n\t\t\t\tdata-testid={`rich-text.${name}`}\n\t\t\t\ttype=\"icon\"\n\t\t\t\tisActive={isActive} // todo: we need to update this only when the text editor \"settles\", ie not during a change of selection\n\t\t\t\tonPointerDown={preventDefault}\n\t\t\t\tonClick={onSelect}\n\t\t\t\trole=\"option\"\n\t\t\t\taria-pressed={isActive}\n\t\t\t>\n\t\t\t\t<TldrawUiButtonIcon small icon={name} />\n\t\t\t</TldrawUiToolbarButton>\n\t\t)\n\t})\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA+HI;AA/HJ,oBAAyD;AACzD,mBAA6C;AAC7C,oBAA4B;AAC5B,4BAA+B;AAC/B,gCAAmC;AACnC,6BAAsC;AAa/B,SAAS,8BAA8B;AAAA,EAC7C;AAAA,EACA;AACD,GAAuC;AACtC,QAAM,iBAAa,2BAAY;AAC/B,QAAM,UAAM,sCAAe;AAC3B,QAAM,SAAS;AAGf,QAAM,CAAC,GAAG,GAAG,QAAI,uBAAS,CAAC;AAC3B;AAAA,IACC,SAAS,gCAAgC;AACxC,eAAS,cAAc;AACtB,YAAI,CAAC,MAAM,IAAI,CAAC;AAAA,MACjB;AACA,iBAAW,GAAG,UAAU,WAAW;AACnC,iBAAW,GAAG,mBAAmB,WAAW;AAAA,IAC7C;AAAA,IACA,CAAC,UAAU;AAAA,EACZ;AAEA,8BAAU,MAAM;AACf,aAAS,cAAc,OAAsB;AAC5C,UAAI,uBAAmB,0BAAW,KAAK,KAAK,MAAM,YAAY,MAAM,QAAQ,KAAK;AAChF,cAAM,eAAe;AACrB,wBAAgB;AAAA,MACjB;AAAA,IACD;AAEA,aAAS,iBAAiB,WAAW,aAAa;AAClD,WAAO,MAAM;AACZ,eAAS,oBAAoB,WAAW,aAAa;AAAA,IACtD;AAAA,EACD,GAAG,CAAC,eAAe,CAAC;AAGpB,QAAM,cAAU,sBAAQ,MAAM;AAC7B,aAAS,SAAS,MAAc,IAAY;AAE3C,UAAI,CAAC,WAAW,KAAM;AAEtB,iBAAW,aAAa,EAAE,WAAW,MAAa,OAAO,CAAC;AAE1D,iBAAW,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI;AAAA,IACtC;AAEA,WAAO;AAAA;AAAA,MAEN;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,QAAQ,YAAY;AAAA,QAC9B;AAAA,MACD;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,QAAQ,cAAc;AAAA,QAChC;AAAA,MACD;AAAA;AAAA;AAAA,MAGA;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,QAAQ,YAAY;AAAA,QAC9B;AAAA,MACD;AAAA,MACA,kBACG;AAAA,QACA,MAAM;AAAA,QACN,WAAW;AACV,0BAAgB;AAAA,QACjB;AAAA,MACD,IACC;AAAA;AAAA,MACH;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,cAAc,kBAAkB;AAAA,QAC1C;AAAA,MACD;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,cAAc,iBAAiB;AAAA,QACzC;AAAA,MACD;AAAA,IACD,EAAE,OAAO,OAAO;AAAA,EAKjB,GAAG,CAAC,YAAY,YAAY,eAAe,CAAC;AAE5C,SAAO,QAAQ,IAAI,CAAC,EAAE,MAAM,OAAO,SAAS,MAAM;AACjD,UAAM,WAAW,WAAW,OAAO,WAAW,SAAS,MAAM,KAAK,IAAI;AACtE,WACC;AAAA,MAAC;AAAA;AAAA,QAEA,OAAO,IAAI,kBAAkB,IAAI,EAAE;AAAA,QACnC,eAAa,aAAa,IAAI;AAAA,QAC9B,MAAK;AAAA,QACL;AAAA,QACA,eAAe;AAAA,QACf,SAAS;AAAA,QACT,MAAK;AAAA,QACL,gBAAc;AAAA,QAEd,sDAAC,gDAAmB,OAAK,MAAC,MAAM,MAAM;AAAA;AAAA,MAVjC;AAAA,IAWN;AAAA,EAEF,CAAC;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -45,12 +45,12 @@ const namedClassNamesSoThatICanGrepForThis = {
|
|
|
45
45
|
help: "tlui-button__help"
|
|
46
46
|
};
|
|
47
47
|
const TldrawUiButton = React.forwardRef(
|
|
48
|
-
function TldrawUiButton2({ children, type, isActive, ...props }, ref) {
|
|
48
|
+
function TldrawUiButton2({ children, type, htmlButtonType, isActive, ...props }, ref) {
|
|
49
49
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
50
50
|
"button",
|
|
51
51
|
{
|
|
52
52
|
ref,
|
|
53
|
-
type: "button",
|
|
53
|
+
type: htmlButtonType || "button",
|
|
54
54
|
draggable: false,
|
|
55
55
|
"data-isactive": isActive,
|
|
56
56
|
...props,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/lib/ui/components/primitives/Button/TldrawUiButton.tsx"],
|
|
4
|
-
"sourcesContent": ["import classnames from 'classnames'\nimport * as React from 'react'\n\n/** @public */\nexport interface TLUiButtonProps extends React.HTMLAttributes<HTMLButtonElement> {\n\tdisabled?: boolean\n\tisActive?: boolean\n\ttype: 'normal' | 'primary' | 'danger' | 'low' | 'icon' | 'tool' | 'menu' | 'help'\n}\n\nconst namedClassNamesSoThatICanGrepForThis = {\n\tnormal: 'tlui-button__normal',\n\tprimary: 'tlui-button__primary',\n\tdanger: 'tlui-button__danger',\n\tlow: 'tlui-button__low',\n\ticon: 'tlui-button__icon',\n\ttool: 'tlui-button__tool',\n\tmenu: 'tlui-button__menu',\n\thelp: 'tlui-button__help',\n}\n\n/** @public @react */\nexport const TldrawUiButton = React.forwardRef<HTMLButtonElement, TLUiButtonProps>(\n\tfunction TldrawUiButton({ children, type, isActive, ...props }, ref) {\n\t\treturn (\n\t\t\t<button\n\t\t\t\tref={ref}\n\t\t\t\ttype
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import classnames from 'classnames'\nimport * as React from 'react'\n\n/** @public */\nexport interface TLUiButtonProps extends React.HTMLAttributes<HTMLButtonElement> {\n\tdisabled?: boolean\n\tisActive?: boolean\n\ttype: 'normal' | 'primary' | 'danger' | 'low' | 'icon' | 'tool' | 'menu' | 'help'\n\thtmlButtonType?: 'button' | 'submit' | 'reset'\n}\n\nconst namedClassNamesSoThatICanGrepForThis = {\n\tnormal: 'tlui-button__normal',\n\tprimary: 'tlui-button__primary',\n\tdanger: 'tlui-button__danger',\n\tlow: 'tlui-button__low',\n\ticon: 'tlui-button__icon',\n\ttool: 'tlui-button__tool',\n\tmenu: 'tlui-button__menu',\n\thelp: 'tlui-button__help',\n}\n\n/** @public @react */\nexport const TldrawUiButton = React.forwardRef<HTMLButtonElement, TLUiButtonProps>(\n\tfunction TldrawUiButton({ children, type, htmlButtonType, isActive, ...props }, ref) {\n\t\treturn (\n\t\t\t<button\n\t\t\t\tref={ref}\n\t\t\t\ttype={htmlButtonType || 'button'}\n\t\t\t\tdraggable={false}\n\t\t\t\tdata-isactive={isActive}\n\t\t\t\t{...props}\n\t\t\t\tclassName={classnames(\n\t\t\t\t\t'tlui-button',\n\t\t\t\t\tnamedClassNamesSoThatICanGrepForThis[type],\n\t\t\t\t\tprops.className\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</button>\n\t\t)\n\t}\n)\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA0BG;AA1BH,wBAAuB;AACvB,YAAuB;AAUvB,MAAM,uCAAuC;AAAA,EAC5C,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACP;AAGO,MAAM,iBAAiB,MAAM;AAAA,EACnC,SAASA,gBAAe,EAAE,UAAU,MAAM,gBAAgB,UAAU,GAAG,MAAM,GAAG,KAAK;AACpF,WACC;AAAA,MAAC;AAAA;AAAA,QACA;AAAA,QACA,MAAM,kBAAkB;AAAA,QACxB,WAAW;AAAA,QACX,iBAAe;AAAA,QACd,GAAG;AAAA,QACJ,eAAW,kBAAAC;AAAA,UACV;AAAA,UACA,qCAAqC,IAAI;AAAA,UACzC,MAAM;AAAA,QACP;AAAA,QAEC;AAAA;AAAA,IACF;AAAA,EAEF;AACD;",
|
|
6
6
|
"names": ["TldrawUiButton", "classnames"]
|
|
7
7
|
}
|
|
@@ -82,7 +82,8 @@ function TldrawUiMenuItem({
|
|
|
82
82
|
children: [
|
|
83
83
|
iconLeft && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiButtonIcon.TldrawUiButtonIcon, { icon: iconLeft, small: true }),
|
|
84
84
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiButtonLabel.TldrawUiButtonLabel, { children: labelStr }),
|
|
85
|
-
kbd && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiKbd.TldrawUiKbd, { children: kbd })
|
|
85
|
+
kbd && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiKbd.TldrawUiKbd, { children: kbd }),
|
|
86
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiButtonIcon.TldrawUiButtonIcon, { icon, small: true })
|
|
86
87
|
]
|
|
87
88
|
}
|
|
88
89
|
) });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n\texhaustiveSwitchError,\n\tgetPointerInfo,\n\tpreventDefault,\n\tTLPointerEventInfo,\n\tuseEditor,\n\tVec,\n\tVecModel,\n} from '@tldraw/editor'\nimport { ContextMenu as _ContextMenu } from 'radix-ui'\nimport { useMemo, useState } from 'react'\nimport { unwrapLabel } from '../../../context/actions'\nimport { TLUiEventSource } from '../../../context/events'\nimport { useReadonly } from '../../../hooks/useReadonly'\nimport { TLUiToolItem } from '../../../hooks/useTools'\nimport { TLUiTranslationKey } from '../../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../../hooks/useTranslation/useTranslation'\nimport { kbdStr } from '../../../kbd-utils'\nimport { Spinner } from '../../Spinner'\nimport { TldrawUiButton } from '../Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from '../Button/TldrawUiButtonIcon'\nimport { TldrawUiButtonLabel } from '../Button/TldrawUiButtonLabel'\nimport { TldrawUiDropdownMenuItem } from '../TldrawUiDropdownMenu'\nimport { TLUiIconJsx } from '../TldrawUiIcon'\nimport { TldrawUiKbd } from '../TldrawUiKbd'\nimport { TldrawUiToolbarButton } from '../TldrawUiToolbar'\nimport { tooltipManager } from '../TldrawUiTooltip'\nimport { useTldrawUiMenuContext } from './TldrawUiMenuContext'\n\n/** @public */\nexport interface TLUiMenuItemProps<\n\tTranslationKey extends string = string,\n\tIconType extends string = string,\n> {\n\tid: string\n\t/**\n\t * The icon to display on the item. Icons are only shown in certain menu types.\n\t */\n\ticon?: IconType | TLUiIconJsx\n\t/**\n\t * An icon to display to the left of the menu item.\n\t */\n\ticonLeft?: IconType | TLUiIconJsx\n\t/**\n\t * The keyboard shortcut to display on the item.\n\t */\n\tkbd?: string\n\t/**\n\t * The label to display on the item. If it's a string, it will be translated. If it's an object, the keys will be used as the language keys and the values will be translated.\n\t */\n\tlabel?: TranslationKey | { [key: string]: TranslationKey }\n\t/**\n\t * If the editor is in readonly mode and the item is not marked as readonlyok, it will not be rendered.\n\t */\n\treadonlyOk?: boolean\n\t/**\n\t * The function to call when the item is clicked.\n\t */\n\tonSelect(source: TLUiEventSource): Promise<void> | void\n\t/**\n\t * Whether this item should be disabled.\n\t */\n\tdisabled?: boolean\n\t/**\n\t * Prevent the menu from closing when the item is clicked\n\t */\n\tnoClose?: boolean\n\t/**\n\t * Whether to show a spinner on the item.\n\t */\n\tspinner?: boolean\n\t/**\n\t * Whether the item is selected.\n\t */\n\tisSelected?: boolean\n\t/**\n\t * The function to call when the item is dragged. If this is provided, the item will be draggable.\n\t */\n\tonDragStart?(source: TLUiEventSource, info: TLPointerEventInfo): void\n}\n\n/** @public @react */\nexport function TldrawUiMenuItem<\n\tTranslationKey extends string = string,\n\tIconType extends string = string,\n>({\n\tdisabled = false,\n\tspinner = false,\n\treadonlyOk = false,\n\tid,\n\tkbd,\n\tlabel,\n\ticon,\n\ticonLeft,\n\tonSelect,\n\tnoClose,\n\tisSelected,\n\tonDragStart,\n}: TLUiMenuItemProps<TranslationKey, IconType>) {\n\tconst { type: menuType, sourceId } = useTldrawUiMenuContext()\n\n\tconst msg = useTranslation()\n\n\tconst [disableClicks, setDisableClicks] = useState(false)\n\n\tconst isReadonlyMode = useReadonly()\n\tif (isReadonlyMode && !readonlyOk) return null\n\n\tconst labelToUse = unwrapLabel(label, menuType)\n\tconst kbdToUse = kbd ? kbdStr(kbd) : undefined\n\n\tconst labelStr = labelToUse ? msg(labelToUse as TLUiTranslationKey) : undefined\n\tconst titleStr = labelStr && kbdToUse ? `${labelStr} ${kbdToUse}` : labelStr\n\n\tswitch (menuType) {\n\t\tcase 'menu': {\n\t\t\treturn (\n\t\t\t\t<TldrawUiDropdownMenuItem>\n\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\ttype=\"menu\"\n\t\t\t\t\t\tdata-testid={`${sourceId}.${id}`}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\tif (noClose) {\n\t\t\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (disableClicks) {\n\t\t\t\t\t\t\t\tsetDisableClicks(false)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tonSelect(sourceId)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{iconLeft && <TldrawUiButtonIcon icon={iconLeft} small />}\n\t\t\t\t\t\t<TldrawUiButtonLabel>{labelStr}</TldrawUiButtonLabel>\n\t\t\t\t\t\t{kbd && <TldrawUiKbd>{kbd}</TldrawUiKbd>}\n\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t</TldrawUiDropdownMenuItem>\n\t\t\t)\n\t\t}\n\t\tcase 'context-menu': {\n\t\t\t// Hide disabled context menu items\n\t\t\tif (disabled) return null\n\n\t\t\treturn (\n\t\t\t\t<_ContextMenu.Item\n\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\tdraggable={false}\n\t\t\t\t\tclassName=\"tlui-button tlui-button__menu\"\n\t\t\t\t\tdata-testid={`${sourceId}.${id}`}\n\t\t\t\t\tonSelect={(e) => {\n\t\t\t\t\t\tif (noClose) preventDefault(e)\n\t\t\t\t\t\tif (disableClicks) {\n\t\t\t\t\t\t\tsetDisableClicks(false)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tonSelect(sourceId)\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<span className=\"tlui-button__label\" draggable={false}>\n\t\t\t\t\t\t{labelStr}\n\t\t\t\t\t</span>\n\t\t\t\t\t{iconLeft && <TldrawUiButtonIcon icon={iconLeft} small />}\n\t\t\t\t\t{kbd && <TldrawUiKbd>{kbd}</TldrawUiKbd>}\n\t\t\t\t\t{spinner && <Spinner />}\n\t\t\t\t</_ContextMenu.Item>\n\t\t\t)\n\t\t}\n\t\tcase 'small-icons':\n\t\tcase 'icons': {\n\t\t\treturn (\n\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\tdata-testid={`${sourceId}.${id}`}\n\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\ttitle={titleStr}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tonClick={() => onSelect(sourceId)}\n\t\t\t\t>\n\t\t\t\t\t<TldrawUiButtonIcon icon={icon!} small />\n\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t)\n\t\t}\n\t\tcase 'keyboard-shortcuts': {\n\t\t\tif (!kbd) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`Menu item '${label}' isn't shown in the keyboard shortcuts dialog because it doesn't have a keyboard shortcut.`\n\t\t\t\t)\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\treturn (\n\t\t\t\t<div className=\"tlui-shortcuts-dialog__key-pair\" data-testid={`${sourceId}.${id}`}>\n\t\t\t\t\t<div className=\"tlui-shortcuts-dialog__key-pair__key\">{labelStr}</div>\n\t\t\t\t\t<div className=\"tlui-shortcuts-dialog__key-pair__value\">\n\t\t\t\t\t\t<TldrawUiKbd visibleOnMobileLayout>{kbd}</TldrawUiKbd>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)\n\t\t}\n\t\tcase 'helper-buttons': {\n\t\t\treturn (\n\t\t\t\t<TldrawUiButton type=\"low\" onClick={() => onSelect(sourceId)}>\n\t\t\t\t\t<TldrawUiButtonIcon icon={icon!} />\n\t\t\t\t\t<TldrawUiButtonLabel>{labelStr}</TldrawUiButtonLabel>\n\t\t\t\t</TldrawUiButton>\n\t\t\t)\n\t\t}\n\t\tcase 'toolbar': {\n\t\t\tif (onDragStart) {\n\t\t\t\treturn (\n\t\t\t\t\t<DraggableToolbarButton\n\t\t\t\t\t\tid={id}\n\t\t\t\t\t\ticon={icon}\n\t\t\t\t\t\tonSelect={onSelect}\n\t\t\t\t\t\tonDragStart={onDragStart}\n\t\t\t\t\t\tlabelStr={labelStr}\n\t\t\t\t\t\ttitleStr={titleStr}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tisSelected={isSelected}\n\t\t\t\t\t/>\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn (\n\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\taria-label={labelStr}\n\t\t\t\t\taria-pressed={isSelected ? 'true' : 'false'}\n\t\t\t\t\tdata-testid={`tools.${id}`}\n\t\t\t\t\tdata-value={id}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tonClick={() => onSelect('toolbar')}\n\t\t\t\t\tonTouchStart={(e) => {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t\tonSelect('toolbar')\n\t\t\t\t\t}}\n\t\t\t\t\ttitle={titleStr}\n\t\t\t\t\ttype=\"tool\"\n\t\t\t\t>\n\t\t\t\t\t<TldrawUiButtonIcon icon={icon!} />\n\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t)\n\t\t}\n\t\tcase 'toolbar-overflow': {\n\t\t\tif (onDragStart) {\n\t\t\t\treturn (\n\t\t\t\t\t<DraggableToolbarButton\n\t\t\t\t\t\tid={id}\n\t\t\t\t\t\ticon={icon}\n\t\t\t\t\t\tonSelect={onSelect}\n\t\t\t\t\t\tonDragStart={onDragStart}\n\t\t\t\t\t\tlabelStr={labelStr}\n\t\t\t\t\t\ttitleStr={titleStr}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tisSelected={isSelected}\n\t\t\t\t\t\toverflow\n\t\t\t\t\t/>\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn (\n\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\taria-label={labelStr}\n\t\t\t\t\taria-pressed={isSelected ? 'true' : 'false'}\n\t\t\t\t\tisActive={isSelected}\n\t\t\t\t\tdata-testid={`tools.more.${id}`}\n\t\t\t\t\tdata-value={id}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tonClick={() => onSelect('toolbar')}\n\t\t\t\t\ttitle={titleStr}\n\t\t\t\t\ttype=\"icon\"\n\t\t\t\t>\n\t\t\t\t\t<TldrawUiButtonIcon icon={icon!} />\n\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t)\n\t\t}\n\t\tdefault: {\n\t\t\tthrow exhaustiveSwitchError(menuType)\n\t\t}\n\t}\n}\n\nfunction useDraggableEvents(\n\tonDragStart: TLUiToolItem['onDragStart'],\n\tonSelect: TLUiToolItem['onSelect']\n) {\n\tconst editor = useEditor()\n\tconst events = useMemo(() => {\n\t\tlet state = { name: 'idle' } as\n\t\t\t| {\n\t\t\t\t\tname: 'idle'\n\t\t\t }\n\t\t\t| {\n\t\t\t\t\tname: 'pointing'\n\t\t\t\t\tscreenSpaceStart: VecModel\n\t\t\t }\n\t\t\t| {\n\t\t\t\t\tname: 'dragging'\n\t\t\t\t\tscreenSpaceStart: VecModel\n\t\t\t }\n\t\t\t| {\n\t\t\t\t\tname: 'dragged'\n\t\t\t }\n\n\t\tfunction handlePointerDown(e: React.PointerEvent<HTMLButtonElement>) {\n\t\t\tstate = {\n\t\t\t\tname: 'pointing',\n\t\t\t\tscreenSpaceStart: { x: e.clientX, y: e.clientY },\n\t\t\t}\n\n\t\t\te.currentTarget.setPointerCapture(e.pointerId)\n\t\t}\n\n\t\tfunction handlePointerMove(e: React.PointerEvent<HTMLButtonElement>) {\n\t\t\tif ((e as any).isSpecialRedispatchedEvent) return\n\n\t\t\tif (state.name === 'pointing') {\n\t\t\t\tconst distanceSq = Vec.Dist2(state.screenSpaceStart, { x: e.clientX, y: e.clientY })\n\t\t\t\tif (\n\t\t\t\t\tdistanceSq >\n\t\t\t\t\t(editor.getInstanceState().isCoarsePointer\n\t\t\t\t\t\t? editor.options.uiCoarseDragDistanceSquared\n\t\t\t\t\t\t: editor.options.uiDragDistanceSquared)\n\t\t\t\t) {\n\t\t\t\t\tconst screenSpaceStart = state.screenSpaceStart\n\t\t\t\t\tstate = {\n\t\t\t\t\t\tname: 'dragging',\n\t\t\t\t\t\tscreenSpaceStart,\n\t\t\t\t\t}\n\n\t\t\t\t\teditor.run(() => {\n\t\t\t\t\t\teditor.setCurrentTool('select')\n\n\t\t\t\t\t\t// Set origin point\n\t\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t\t\t\tpoint: screenSpaceStart,\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\t// Pointer down potentially selects shapes, so we need to deselect them.\n\t\t\t\t\t\teditor.selectNone()\n\n\t\t\t\t\t\t// start drag\n\t\t\t\t\t\tonDragStart?.('toolbar', {\n\t\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t\t\t\tpoint: screenSpaceStart,\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\ttooltipManager.hideAllTooltips()\n\t\t\t\t\t\teditor.getContainer().focus()\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfunction handlePointerUp(e: React.PointerEvent<HTMLButtonElement>) {\n\t\t\tif ((e as any).isSpecialRedispatchedEvent) return\n\n\t\t\te.currentTarget.releasePointerCapture(e.pointerId)\n\n\t\t\teditor.dispatch({\n\t\t\t\ttype: 'pointer',\n\t\t\t\ttarget: 'canvas',\n\t\t\t\tname: 'pointer_up',\n\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t})\n\t\t}\n\n\t\tfunction handleClick() {\n\t\t\tif (state.name === 'dragging' || state.name === 'dragged') {\n\t\t\t\tstate = { name: 'idle' }\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\tstate = { name: 'idle' }\n\t\t\tonSelect?.('toolbar')\n\t\t}\n\n\t\treturn {\n\t\t\tonPointerDown: handlePointerDown,\n\t\t\tonPointerMove: handlePointerMove,\n\t\t\tonPointerUp: handlePointerUp,\n\t\t\tonClick: handleClick,\n\t\t}\n\t}, [onDragStart, editor, onSelect])\n\n\treturn events\n}\n\nfunction DraggableToolbarButton({\n\tid,\n\tlabelStr,\n\ttitleStr,\n\tdisabled,\n\tisSelected,\n\ticon,\n\tonSelect,\n\tonDragStart,\n\toverflow,\n}: {\n\tid: string\n\tdisabled: boolean\n\tlabelStr?: string\n\ttitleStr?: string\n\tisSelected?: boolean\n\ticon: TLUiMenuItemProps['icon']\n\tonSelect: TLUiMenuItemProps['onSelect']\n\tonDragStart: TLUiMenuItemProps['onDragStart']\n\toverflow?: boolean\n}) {\n\tconst events = useDraggableEvents(onDragStart, onSelect)\n\n\tif (overflow) {\n\t\treturn (\n\t\t\t<TldrawUiToolbarButton\n\t\t\t\taria-label={labelStr}\n\t\t\t\taria-pressed={isSelected ? 'true' : 'false'}\n\t\t\t\tisActive={isSelected}\n\t\t\t\tclassName=\"tlui-button-grid__button\"\n\t\t\t\tdata-testid={`tools.more.${id}`}\n\t\t\t\tdata-value={id}\n\t\t\t\tdisabled={disabled}\n\t\t\t\ttitle={titleStr}\n\t\t\t\ttype=\"icon\"\n\t\t\t\t{...events}\n\t\t\t>\n\t\t\t\t<TldrawUiButtonIcon icon={icon!} />\n\t\t\t</TldrawUiToolbarButton>\n\t\t)\n\t}\n\n\treturn (\n\t\t<TldrawUiToolbarButton\n\t\t\taria-label={labelStr}\n\t\t\taria-pressed={isSelected ? 'true' : 'false'}\n\t\t\tdata-testid={`tools.${id}`}\n\t\t\tdata-value={id}\n\t\t\tdisabled={disabled}\n\t\t\tonTouchStart={(e) => {\n\t\t\t\tpreventDefault(e)\n\t\t\t\tonSelect('toolbar')\n\t\t\t}}\n\t\t\ttitle={titleStr}\n\t\t\ttype=\"tool\"\n\t\t\t{...events}\n\t\t>\n\t\t\t<TldrawUiButtonIcon icon={icon!} />\n\t\t</TldrawUiToolbarButton>\n\t)\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsHK;AAtHL,oBAQO;AACP,sBAA4C;AAC5C,mBAAkC;AAClC,qBAA4B;AAE5B,yBAA4B;AAG5B,4BAA+B;AAC/B,uBAAuB;AACvB,qBAAwB;AACxB,4BAA+B;AAC/B,gCAAmC;AACnC,iCAAoC;AACpC,kCAAyC;AAEzC,yBAA4B;AAC5B,6BAAsC;AACtC,6BAA+B;AAC/B,iCAAuC;AAuDhC,SAAS,iBAGd;AAAA,EACD,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAgD;AAC/C,QAAM,EAAE,MAAM,UAAU,SAAS,QAAI,mDAAuB;AAE5D,QAAM,UAAM,sCAAe;AAE3B,QAAM,CAAC,eAAe,gBAAgB,QAAI,uBAAS,KAAK;AAExD,QAAM,qBAAiB,gCAAY;AACnC,MAAI,kBAAkB,CAAC,WAAY,QAAO;AAE1C,QAAM,iBAAa,4BAAY,OAAO,QAAQ;AAC9C,QAAM,WAAW,UAAM,yBAAO,GAAG,IAAI;AAErC,QAAM,WAAW,aAAa,IAAI,UAAgC,IAAI;AACtE,QAAM,WAAW,YAAY,WAAW,GAAG,QAAQ,IAAI,QAAQ,KAAK;AAEpE,UAAQ,UAAU;AAAA,IACjB,KAAK,QAAQ;AACZ,aACC,4CAAC,wDACA;AAAA,QAAC;AAAA;AAAA,UACA,MAAK;AAAA,UACL,eAAa,GAAG,QAAQ,IAAI,EAAE;AAAA,UAC9B;AAAA,UACA,SAAS,CAAC,MAAM;AACf,gBAAI,SAAS;AACZ,gDAAe,CAAC;AAAA,YACjB;AACA,gBAAI,eAAe;AAClB,+BAAiB,KAAK;AAAA,YACvB,OAAO;AACN,uBAAS,QAAQ;AAAA,YAClB;AAAA,UACD;AAAA,UAEC;AAAA,wBAAY,4CAAC,gDAAmB,MAAM,UAAU,OAAK,MAAC;AAAA,YACvD,4CAAC,kDAAqB,oBAAS;AAAA,YAC9B,OAAO,4CAAC,kCAAa,eAAI;AAAA;AAAA;AAAA,
|
|
4
|
+
"sourcesContent": ["import {\n\texhaustiveSwitchError,\n\tgetPointerInfo,\n\tpreventDefault,\n\tTLPointerEventInfo,\n\tuseEditor,\n\tVec,\n\tVecModel,\n} from '@tldraw/editor'\nimport { ContextMenu as _ContextMenu } from 'radix-ui'\nimport { useMemo, useState } from 'react'\nimport { unwrapLabel } from '../../../context/actions'\nimport { TLUiEventSource } from '../../../context/events'\nimport { useReadonly } from '../../../hooks/useReadonly'\nimport { TLUiToolItem } from '../../../hooks/useTools'\nimport { TLUiTranslationKey } from '../../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../../hooks/useTranslation/useTranslation'\nimport { kbdStr } from '../../../kbd-utils'\nimport { Spinner } from '../../Spinner'\nimport { TldrawUiButton } from '../Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from '../Button/TldrawUiButtonIcon'\nimport { TldrawUiButtonLabel } from '../Button/TldrawUiButtonLabel'\nimport { TldrawUiDropdownMenuItem } from '../TldrawUiDropdownMenu'\nimport { TLUiIconJsx } from '../TldrawUiIcon'\nimport { TldrawUiKbd } from '../TldrawUiKbd'\nimport { TldrawUiToolbarButton } from '../TldrawUiToolbar'\nimport { tooltipManager } from '../TldrawUiTooltip'\nimport { useTldrawUiMenuContext } from './TldrawUiMenuContext'\n\n/** @public */\nexport interface TLUiMenuItemProps<\n\tTranslationKey extends string = string,\n\tIconType extends string = string,\n> {\n\tid: string\n\t/**\n\t * The icon to display on the item. Icons are only shown in certain menu types.\n\t */\n\ticon?: IconType | TLUiIconJsx\n\t/**\n\t * An icon to display to the left of the menu item.\n\t */\n\ticonLeft?: IconType | TLUiIconJsx\n\t/**\n\t * The keyboard shortcut to display on the item.\n\t */\n\tkbd?: string\n\t/**\n\t * The label to display on the item. If it's a string, it will be translated. If it's an object, the keys will be used as the language keys and the values will be translated.\n\t */\n\tlabel?: TranslationKey | { [key: string]: TranslationKey }\n\t/**\n\t * If the editor is in readonly mode and the item is not marked as readonlyok, it will not be rendered.\n\t */\n\treadonlyOk?: boolean\n\t/**\n\t * The function to call when the item is clicked.\n\t */\n\tonSelect(source: TLUiEventSource): Promise<void> | void\n\t/**\n\t * Whether this item should be disabled.\n\t */\n\tdisabled?: boolean\n\t/**\n\t * Prevent the menu from closing when the item is clicked\n\t */\n\tnoClose?: boolean\n\t/**\n\t * Whether to show a spinner on the item.\n\t */\n\tspinner?: boolean\n\t/**\n\t * Whether the item is selected.\n\t */\n\tisSelected?: boolean\n\t/**\n\t * The function to call when the item is dragged. If this is provided, the item will be draggable.\n\t */\n\tonDragStart?(source: TLUiEventSource, info: TLPointerEventInfo): void\n}\n\n/** @public @react */\nexport function TldrawUiMenuItem<\n\tTranslationKey extends string = string,\n\tIconType extends string = string,\n>({\n\tdisabled = false,\n\tspinner = false,\n\treadonlyOk = false,\n\tid,\n\tkbd,\n\tlabel,\n\ticon,\n\ticonLeft,\n\tonSelect,\n\tnoClose,\n\tisSelected,\n\tonDragStart,\n}: TLUiMenuItemProps<TranslationKey, IconType>) {\n\tconst { type: menuType, sourceId } = useTldrawUiMenuContext()\n\n\tconst msg = useTranslation()\n\n\tconst [disableClicks, setDisableClicks] = useState(false)\n\n\tconst isReadonlyMode = useReadonly()\n\tif (isReadonlyMode && !readonlyOk) return null\n\n\tconst labelToUse = unwrapLabel(label, menuType)\n\tconst kbdToUse = kbd ? kbdStr(kbd) : undefined\n\n\tconst labelStr = labelToUse ? msg(labelToUse as TLUiTranslationKey) : undefined\n\tconst titleStr = labelStr && kbdToUse ? `${labelStr} ${kbdToUse}` : labelStr\n\n\tswitch (menuType) {\n\t\tcase 'menu': {\n\t\t\treturn (\n\t\t\t\t<TldrawUiDropdownMenuItem>\n\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\ttype=\"menu\"\n\t\t\t\t\t\tdata-testid={`${sourceId}.${id}`}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\tif (noClose) {\n\t\t\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (disableClicks) {\n\t\t\t\t\t\t\t\tsetDisableClicks(false)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tonSelect(sourceId)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{iconLeft && <TldrawUiButtonIcon icon={iconLeft} small />}\n\t\t\t\t\t\t<TldrawUiButtonLabel>{labelStr}</TldrawUiButtonLabel>\n\t\t\t\t\t\t{kbd && <TldrawUiKbd>{kbd}</TldrawUiKbd>}\n\t\t\t\t\t\t{icon && <TldrawUiButtonIcon icon={icon} small />}\n\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t</TldrawUiDropdownMenuItem>\n\t\t\t)\n\t\t}\n\t\tcase 'context-menu': {\n\t\t\t// Hide disabled context menu items\n\t\t\tif (disabled) return null\n\n\t\t\treturn (\n\t\t\t\t<_ContextMenu.Item\n\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\tdraggable={false}\n\t\t\t\t\tclassName=\"tlui-button tlui-button__menu\"\n\t\t\t\t\tdata-testid={`${sourceId}.${id}`}\n\t\t\t\t\tonSelect={(e) => {\n\t\t\t\t\t\tif (noClose) preventDefault(e)\n\t\t\t\t\t\tif (disableClicks) {\n\t\t\t\t\t\t\tsetDisableClicks(false)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tonSelect(sourceId)\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<span className=\"tlui-button__label\" draggable={false}>\n\t\t\t\t\t\t{labelStr}\n\t\t\t\t\t</span>\n\t\t\t\t\t{iconLeft && <TldrawUiButtonIcon icon={iconLeft} small />}\n\t\t\t\t\t{kbd && <TldrawUiKbd>{kbd}</TldrawUiKbd>}\n\t\t\t\t\t{spinner && <Spinner />}\n\t\t\t\t</_ContextMenu.Item>\n\t\t\t)\n\t\t}\n\t\tcase 'small-icons':\n\t\tcase 'icons': {\n\t\t\treturn (\n\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\tdata-testid={`${sourceId}.${id}`}\n\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\ttitle={titleStr}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tonClick={() => onSelect(sourceId)}\n\t\t\t\t>\n\t\t\t\t\t<TldrawUiButtonIcon icon={icon!} small />\n\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t)\n\t\t}\n\t\tcase 'keyboard-shortcuts': {\n\t\t\tif (!kbd) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`Menu item '${label}' isn't shown in the keyboard shortcuts dialog because it doesn't have a keyboard shortcut.`\n\t\t\t\t)\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\treturn (\n\t\t\t\t<div className=\"tlui-shortcuts-dialog__key-pair\" data-testid={`${sourceId}.${id}`}>\n\t\t\t\t\t<div className=\"tlui-shortcuts-dialog__key-pair__key\">{labelStr}</div>\n\t\t\t\t\t<div className=\"tlui-shortcuts-dialog__key-pair__value\">\n\t\t\t\t\t\t<TldrawUiKbd visibleOnMobileLayout>{kbd}</TldrawUiKbd>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)\n\t\t}\n\t\tcase 'helper-buttons': {\n\t\t\treturn (\n\t\t\t\t<TldrawUiButton type=\"low\" onClick={() => onSelect(sourceId)}>\n\t\t\t\t\t<TldrawUiButtonIcon icon={icon!} />\n\t\t\t\t\t<TldrawUiButtonLabel>{labelStr}</TldrawUiButtonLabel>\n\t\t\t\t</TldrawUiButton>\n\t\t\t)\n\t\t}\n\t\tcase 'toolbar': {\n\t\t\tif (onDragStart) {\n\t\t\t\treturn (\n\t\t\t\t\t<DraggableToolbarButton\n\t\t\t\t\t\tid={id}\n\t\t\t\t\t\ticon={icon}\n\t\t\t\t\t\tonSelect={onSelect}\n\t\t\t\t\t\tonDragStart={onDragStart}\n\t\t\t\t\t\tlabelStr={labelStr}\n\t\t\t\t\t\ttitleStr={titleStr}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tisSelected={isSelected}\n\t\t\t\t\t/>\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn (\n\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\taria-label={labelStr}\n\t\t\t\t\taria-pressed={isSelected ? 'true' : 'false'}\n\t\t\t\t\tdata-testid={`tools.${id}`}\n\t\t\t\t\tdata-value={id}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tonClick={() => onSelect('toolbar')}\n\t\t\t\t\tonTouchStart={(e) => {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t\tonSelect('toolbar')\n\t\t\t\t\t}}\n\t\t\t\t\ttitle={titleStr}\n\t\t\t\t\ttype=\"tool\"\n\t\t\t\t>\n\t\t\t\t\t<TldrawUiButtonIcon icon={icon!} />\n\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t)\n\t\t}\n\t\tcase 'toolbar-overflow': {\n\t\t\tif (onDragStart) {\n\t\t\t\treturn (\n\t\t\t\t\t<DraggableToolbarButton\n\t\t\t\t\t\tid={id}\n\t\t\t\t\t\ticon={icon}\n\t\t\t\t\t\tonSelect={onSelect}\n\t\t\t\t\t\tonDragStart={onDragStart}\n\t\t\t\t\t\tlabelStr={labelStr}\n\t\t\t\t\t\ttitleStr={titleStr}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tisSelected={isSelected}\n\t\t\t\t\t\toverflow\n\t\t\t\t\t/>\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn (\n\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\taria-label={labelStr}\n\t\t\t\t\taria-pressed={isSelected ? 'true' : 'false'}\n\t\t\t\t\tisActive={isSelected}\n\t\t\t\t\tdata-testid={`tools.more.${id}`}\n\t\t\t\t\tdata-value={id}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tonClick={() => onSelect('toolbar')}\n\t\t\t\t\ttitle={titleStr}\n\t\t\t\t\ttype=\"icon\"\n\t\t\t\t>\n\t\t\t\t\t<TldrawUiButtonIcon icon={icon!} />\n\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t)\n\t\t}\n\t\tdefault: {\n\t\t\tthrow exhaustiveSwitchError(menuType)\n\t\t}\n\t}\n}\n\nfunction useDraggableEvents(\n\tonDragStart: TLUiToolItem['onDragStart'],\n\tonSelect: TLUiToolItem['onSelect']\n) {\n\tconst editor = useEditor()\n\tconst events = useMemo(() => {\n\t\tlet state = { name: 'idle' } as\n\t\t\t| {\n\t\t\t\t\tname: 'idle'\n\t\t\t }\n\t\t\t| {\n\t\t\t\t\tname: 'pointing'\n\t\t\t\t\tscreenSpaceStart: VecModel\n\t\t\t }\n\t\t\t| {\n\t\t\t\t\tname: 'dragging'\n\t\t\t\t\tscreenSpaceStart: VecModel\n\t\t\t }\n\t\t\t| {\n\t\t\t\t\tname: 'dragged'\n\t\t\t }\n\n\t\tfunction handlePointerDown(e: React.PointerEvent<HTMLButtonElement>) {\n\t\t\tstate = {\n\t\t\t\tname: 'pointing',\n\t\t\t\tscreenSpaceStart: { x: e.clientX, y: e.clientY },\n\t\t\t}\n\n\t\t\te.currentTarget.setPointerCapture(e.pointerId)\n\t\t}\n\n\t\tfunction handlePointerMove(e: React.PointerEvent<HTMLButtonElement>) {\n\t\t\tif ((e as any).isSpecialRedispatchedEvent) return\n\n\t\t\tif (state.name === 'pointing') {\n\t\t\t\tconst distanceSq = Vec.Dist2(state.screenSpaceStart, { x: e.clientX, y: e.clientY })\n\t\t\t\tif (\n\t\t\t\t\tdistanceSq >\n\t\t\t\t\t(editor.getInstanceState().isCoarsePointer\n\t\t\t\t\t\t? editor.options.uiCoarseDragDistanceSquared\n\t\t\t\t\t\t: editor.options.uiDragDistanceSquared)\n\t\t\t\t) {\n\t\t\t\t\tconst screenSpaceStart = state.screenSpaceStart\n\t\t\t\t\tstate = {\n\t\t\t\t\t\tname: 'dragging',\n\t\t\t\t\t\tscreenSpaceStart,\n\t\t\t\t\t}\n\n\t\t\t\t\teditor.run(() => {\n\t\t\t\t\t\teditor.setCurrentTool('select')\n\n\t\t\t\t\t\t// Set origin point\n\t\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t\t\t\tpoint: screenSpaceStart,\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\t// Pointer down potentially selects shapes, so we need to deselect them.\n\t\t\t\t\t\teditor.selectNone()\n\n\t\t\t\t\t\t// start drag\n\t\t\t\t\t\tonDragStart?.('toolbar', {\n\t\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t\t\t\tpoint: screenSpaceStart,\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\ttooltipManager.hideAllTooltips()\n\t\t\t\t\t\teditor.getContainer().focus()\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfunction handlePointerUp(e: React.PointerEvent<HTMLButtonElement>) {\n\t\t\tif ((e as any).isSpecialRedispatchedEvent) return\n\n\t\t\te.currentTarget.releasePointerCapture(e.pointerId)\n\n\t\t\teditor.dispatch({\n\t\t\t\ttype: 'pointer',\n\t\t\t\ttarget: 'canvas',\n\t\t\t\tname: 'pointer_up',\n\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t})\n\t\t}\n\n\t\tfunction handleClick() {\n\t\t\tif (state.name === 'dragging' || state.name === 'dragged') {\n\t\t\t\tstate = { name: 'idle' }\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\tstate = { name: 'idle' }\n\t\t\tonSelect?.('toolbar')\n\t\t}\n\n\t\treturn {\n\t\t\tonPointerDown: handlePointerDown,\n\t\t\tonPointerMove: handlePointerMove,\n\t\t\tonPointerUp: handlePointerUp,\n\t\t\tonClick: handleClick,\n\t\t}\n\t}, [onDragStart, editor, onSelect])\n\n\treturn events\n}\n\nfunction DraggableToolbarButton({\n\tid,\n\tlabelStr,\n\ttitleStr,\n\tdisabled,\n\tisSelected,\n\ticon,\n\tonSelect,\n\tonDragStart,\n\toverflow,\n}: {\n\tid: string\n\tdisabled: boolean\n\tlabelStr?: string\n\ttitleStr?: string\n\tisSelected?: boolean\n\ticon: TLUiMenuItemProps['icon']\n\tonSelect: TLUiMenuItemProps['onSelect']\n\tonDragStart: TLUiMenuItemProps['onDragStart']\n\toverflow?: boolean\n}) {\n\tconst events = useDraggableEvents(onDragStart, onSelect)\n\n\tif (overflow) {\n\t\treturn (\n\t\t\t<TldrawUiToolbarButton\n\t\t\t\taria-label={labelStr}\n\t\t\t\taria-pressed={isSelected ? 'true' : 'false'}\n\t\t\t\tisActive={isSelected}\n\t\t\t\tclassName=\"tlui-button-grid__button\"\n\t\t\t\tdata-testid={`tools.more.${id}`}\n\t\t\t\tdata-value={id}\n\t\t\t\tdisabled={disabled}\n\t\t\t\ttitle={titleStr}\n\t\t\t\ttype=\"icon\"\n\t\t\t\t{...events}\n\t\t\t>\n\t\t\t\t<TldrawUiButtonIcon icon={icon!} />\n\t\t\t</TldrawUiToolbarButton>\n\t\t)\n\t}\n\n\treturn (\n\t\t<TldrawUiToolbarButton\n\t\t\taria-label={labelStr}\n\t\t\taria-pressed={isSelected ? 'true' : 'false'}\n\t\t\tdata-testid={`tools.${id}`}\n\t\t\tdata-value={id}\n\t\t\tdisabled={disabled}\n\t\t\tonTouchStart={(e) => {\n\t\t\t\tpreventDefault(e)\n\t\t\t\tonSelect('toolbar')\n\t\t\t}}\n\t\t\ttitle={titleStr}\n\t\t\ttype=\"tool\"\n\t\t\t{...events}\n\t\t>\n\t\t\t<TldrawUiButtonIcon icon={icon!} />\n\t\t</TldrawUiToolbarButton>\n\t)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["_ContextMenu"]
|
|
7
7
|
}
|
|
@@ -1373,6 +1373,22 @@ function ActionsProvider({ overrides, children }) {
|
|
|
1373
1373
|
trackEvent("set-style", { source, id: style.id, value: "fill" });
|
|
1374
1374
|
}
|
|
1375
1375
|
},
|
|
1376
|
+
{
|
|
1377
|
+
id: "select-fill-lined-fill",
|
|
1378
|
+
label: "fill-style.lined-fill",
|
|
1379
|
+
kbd: "alt+shift+f",
|
|
1380
|
+
onSelect(source) {
|
|
1381
|
+
const style = import_editor.DefaultFillStyle;
|
|
1382
|
+
editor.run(() => {
|
|
1383
|
+
editor.markHistoryStoppingPoint("change-fill");
|
|
1384
|
+
if (editor.isIn("select")) {
|
|
1385
|
+
editor.setStyleForSelectedShapes(style, "lined-fill");
|
|
1386
|
+
}
|
|
1387
|
+
editor.setStyleForNextShapes(style, "lined-fill");
|
|
1388
|
+
});
|
|
1389
|
+
trackEvent("set-style", { source, id: style.id, value: "lined-fill" });
|
|
1390
|
+
}
|
|
1391
|
+
},
|
|
1376
1392
|
{
|
|
1377
1393
|
id: "flatten-to-image",
|
|
1378
1394
|
label: "action.flatten-to-image",
|