tldraw 4.2.0-canary.e45f694a6f24 → 4.2.0-canary.e9477ef82d63
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/RichTextLabel.js +1 -1
- package/dist-cjs/lib/shapes/shared/RichTextLabel.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/DefaultDebugPanel.js +1 -1
- package/dist-cjs/lib/ui/components/DefaultDebugPanel.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/Toolbar/LinkEditor.js +1 -1
- package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.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/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/getLocalFiles.js +18 -3
- package/dist-cjs/lib/ui/getLocalFiles.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/RichTextLabel.mjs +2 -1
- package/dist-esm/lib/shapes/shared/RichTextLabel.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/DefaultDebugPanel.mjs +1 -1
- package/dist-esm/lib/ui/components/DefaultDebugPanel.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/Toolbar/LinkEditor.mjs +2 -2
- package/dist-esm/lib/ui/components/Toolbar/LinkEditor.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/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/getLocalFiles.mjs +18 -3
- package/dist-esm/lib/ui/getLocalFiles.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/RichTextLabel.tsx +2 -1
- 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/DefaultDebugPanel.tsx +1 -1
- 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/Toolbar/LinkEditor.tsx +2 -2
- package/src/lib/ui/components/primitives/Button/TldrawUiButton.tsx +3 -2
- package/src/lib/ui/context/actions.tsx +16 -0
- package/src/lib/ui/context/events.tsx +1 -0
- package/src/lib/ui/getLocalFiles.ts +20 -3
- 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/DefaultDebugPanel.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n\tdebugFlags,\n\ttrack,\n\tuseEditor,\n\tusePassThroughWheelEvents,\n\tuseValue,\n\tVec,\n} from '@tldraw/editor'\nimport { memo, useEffect, useRef, useState } from 'react'\nimport { useTldrawUiComponents } from '../context/components'\n\n/** @internal */\nexport const DefaultDebugPanel = memo(function DefaultDebugPanel() {\n\tconst { DebugMenu } = useTldrawUiComponents()\n\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\treturn (\n\t\t<footer ref={ref} className=\"tlui-debug-panel\">\n\t\t\t<CurrentState />\n\t\t\t<FPS />\n\t\t\t{DebugMenu && <DebugMenu />}\n\t\t</footer>\n\t)\n})\n\nfunction useTick(isEnabled = true) {\n\tconst [_, setTick] = useState(0)\n\tconst editor = useEditor()\n\tuseEffect(() => {\n\t\tif (!isEnabled) return\n\t\tconst update = () => setTick((tick) => tick + 1)\n\t\teditor.on('tick', update)\n\t\treturn () => {\n\t\t\teditor.off('tick', update)\n\t\t}\n\t}, [editor, isEnabled])\n}\n\nconst CurrentState = track(function CurrentState() {\n\tuseTick()\n\n\tconst editor = useEditor()\n\n\tconst path = editor.getPath()\n\tconst hoverShape = editor.getHoveredShape()\n\tconst selectedShape = editor.getOnlySelectedShape()\n\tconst shape = path === 'select.idle' || !path.includes('select.') ? hoverShape : selectedShape\n\tconst shapeInfo =\n\t\tshape && path.includes('select.')\n\t\t\t? ` / ${shape.type || ''}${\n\t\t\t\t\t'geo' in shape.props ? ' / ' + shape.props.geo : ''\n\t\t\t\t} / [${Vec.ToInt(editor.getPointInShapeSpace(shape, editor.inputs.currentPagePoint))}]`\n\t\t\t: ''\n\tconst ruler =\n\t\tpath.startsWith('select.') && !path.includes('.idle')\n\t\t\t? ` / [${Vec.ToInt(editor.inputs.originPagePoint)}] \u2192 [${Vec.ToInt(\n\t\t\t\t\teditor.inputs.currentPagePoint\n\t\t\t\t)}] = ${Vec.Dist(editor.inputs.originPagePoint, editor.inputs.currentPagePoint).toFixed(0)}`\n\t\t\t: ''\n\n\treturn <div className=\"tlui-debug-panel__current-state\">{`${path}${shapeInfo}${ruler}`}</div>\n})\n\nfunction FPS() {\n\tconst editor = useEditor()\n\tconst showFps = useValue('show_fps', () => debugFlags.showFps.get(), [debugFlags])\n\n\tconst fpsRef = useRef<HTMLDivElement>(null)\n\n\tuseEffect(() => {\n\t\tif (!showFps) return\n\n\t\tconst TICK_LENGTH = 250\n\t\tlet maxKnownFps = 0\n\t\tlet raf = -1\n\n\t\tlet start = performance.now()\n\t\tlet currentTickLength = 0\n\t\tlet framesInCurrentTick = 0\n\t\tlet isSlow = false\n\n\t\t// A \"tick\" is the amount of time between renders. Even though\n\t\t// we'll loop on every frame, we will only paint when the time\n\t\t// since the last paint is greater than the tick length.\n\n\t\t// When we paint, we'll calculate the FPS based on the number\n\t\t// of frames that we've seen since the last time we rendered,\n\t\t// and the actual time since the last render.\n\t\tfunction loop() {\n\t\t\t// Count the frame\n\t\t\tframesInCurrentTick++\n\n\t\t\t// Check if we should render\n\t\t\tcurrentTickLength = performance.now() - start\n\n\t\t\tif (currentTickLength > TICK_LENGTH) {\n\t\t\t\t// Calculate the FPS and paint it\n\t\t\t\tconst fps = Math.round(\n\t\t\t\t\tframesInCurrentTick * (TICK_LENGTH / currentTickLength) * (1000 / TICK_LENGTH)\n\t\t\t\t)\n\n\t\t\t\tif (fps > maxKnownFps) {\n\t\t\t\t\tmaxKnownFps = fps\n\t\t\t\t}\n\n\t\t\t\tconst slowFps = maxKnownFps * 0.75\n\t\t\t\tif ((fps < slowFps && !isSlow) || (fps >= slowFps && isSlow)) {\n\t\t\t\t\tisSlow = !isSlow\n\t\t\t\t}\n\n\t\t\t\tfpsRef.current!.innerHTML = `FPS ${fps.toString()}
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBE;AAnBF,oBAOO;AACP,mBAAkD;AAClD,wBAAsC;AAG/B,MAAM,wBAAoB,mBAAK,SAASA,qBAAoB;AAClE,QAAM,EAAE,UAAU,QAAI,yCAAsB;AAE5C,QAAM,UAAM,qBAAuB,IAAI;AACvC,+CAA0B,GAAG;AAE7B,SACC,6CAAC,YAAO,KAAU,WAAU,oBAC3B;AAAA,gDAAC,gBAAa;AAAA,IACd,4CAAC,OAAI;AAAA,IACJ,aAAa,4CAAC,aAAU;AAAA,KAC1B;AAEF,CAAC;AAED,SAAS,QAAQ,YAAY,MAAM;AAClC,QAAM,CAAC,GAAG,OAAO,QAAI,uBAAS,CAAC;AAC/B,QAAM,aAAS,yBAAU;AACzB,8BAAU,MAAM;AACf,QAAI,CAAC,UAAW;AAChB,UAAM,SAAS,MAAM,QAAQ,CAAC,SAAS,OAAO,CAAC;AAC/C,WAAO,GAAG,QAAQ,MAAM;AACxB,WAAO,MAAM;AACZ,aAAO,IAAI,QAAQ,MAAM;AAAA,IAC1B;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,CAAC;AACvB;AAEA,MAAM,mBAAe,qBAAM,SAASC,gBAAe;AAClD,UAAQ;AAER,QAAM,aAAS,yBAAU;AAEzB,QAAM,OAAO,OAAO,QAAQ;AAC5B,QAAM,aAAa,OAAO,gBAAgB;AAC1C,QAAM,gBAAgB,OAAO,qBAAqB;AAClD,QAAM,QAAQ,SAAS,iBAAiB,CAAC,KAAK,SAAS,SAAS,IAAI,aAAa;AACjF,QAAM,YACL,SAAS,KAAK,SAAS,SAAS,IAC7B,MAAM,MAAM,QAAQ,EAAE,GACtB,SAAS,MAAM,QAAQ,QAAQ,MAAM,MAAM,MAAM,EAClD,OAAO,kBAAI,MAAM,OAAO,qBAAqB,OAAO,OAAO,OAAO,gBAAgB,CAAC,CAAC,MACnF;AACJ,QAAM,QACL,KAAK,WAAW,SAAS,KAAK,CAAC,KAAK,SAAS,OAAO,IACjD,OAAO,kBAAI,MAAM,OAAO,OAAO,eAAe,CAAC,aAAQ,kBAAI;AAAA,IAC3D,OAAO,OAAO;AAAA,EACf,CAAC,OAAO,kBAAI,KAAK,OAAO,OAAO,iBAAiB,OAAO,OAAO,gBAAgB,EAAE,QAAQ,CAAC,CAAC,KACzF;AAEJ,SAAO,4CAAC,SAAI,WAAU,mCAAmC,aAAG,IAAI,GAAG,SAAS,GAAG,KAAK,IAAG;AACxF,CAAC;AAED,SAAS,MAAM;AACd,QAAM,aAAS,yBAAU;AACzB,QAAM,cAAU,wBAAS,YAAY,MAAM,yBAAW,QAAQ,IAAI,GAAG,CAAC,wBAAU,CAAC;AAEjF,QAAM,aAAS,qBAAuB,IAAI;AAE1C,8BAAU,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,UAAM,cAAc;AACpB,QAAI,cAAc;AAClB,QAAI,MAAM;AAEV,QAAI,QAAQ,YAAY,IAAI;AAC5B,QAAI,oBAAoB;AACxB,QAAI,sBAAsB;AAC1B,QAAI,SAAS;AASb,aAAS,OAAO;AAEf;AAGA,0BAAoB,YAAY,IAAI,IAAI;AAExC,UAAI,oBAAoB,aAAa;AAEpC,cAAM,MAAM,KAAK;AAAA,UAChB,uBAAuB,cAAc,sBAAsB,MAAO;AAAA,QACnE;AAEA,YAAI,MAAM,aAAa;AACtB,wBAAc;AAAA,QACf;AAEA,cAAM,UAAU,cAAc;AAC9B,YAAK,MAAM,WAAW,CAAC,UAAY,OAAO,WAAW,QAAS;AAC7D,mBAAS,CAAC;AAAA,QACX;AAEA,eAAO,QAAS,YAAY,OAAO,IAAI,SAAS,CAAC
|
|
4
|
+
"sourcesContent": ["import {\n\tdebugFlags,\n\ttrack,\n\tuseEditor,\n\tusePassThroughWheelEvents,\n\tuseValue,\n\tVec,\n} from '@tldraw/editor'\nimport { memo, useEffect, useRef, useState } from 'react'\nimport { useTldrawUiComponents } from '../context/components'\n\n/** @internal */\nexport const DefaultDebugPanel = memo(function DefaultDebugPanel() {\n\tconst { DebugMenu } = useTldrawUiComponents()\n\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\treturn (\n\t\t<footer ref={ref} className=\"tlui-debug-panel\">\n\t\t\t<CurrentState />\n\t\t\t<FPS />\n\t\t\t{DebugMenu && <DebugMenu />}\n\t\t</footer>\n\t)\n})\n\nfunction useTick(isEnabled = true) {\n\tconst [_, setTick] = useState(0)\n\tconst editor = useEditor()\n\tuseEffect(() => {\n\t\tif (!isEnabled) return\n\t\tconst update = () => setTick((tick) => tick + 1)\n\t\teditor.on('tick', update)\n\t\treturn () => {\n\t\t\teditor.off('tick', update)\n\t\t}\n\t}, [editor, isEnabled])\n}\n\nconst CurrentState = track(function CurrentState() {\n\tuseTick()\n\n\tconst editor = useEditor()\n\n\tconst path = editor.getPath()\n\tconst hoverShape = editor.getHoveredShape()\n\tconst selectedShape = editor.getOnlySelectedShape()\n\tconst shape = path === 'select.idle' || !path.includes('select.') ? hoverShape : selectedShape\n\tconst shapeInfo =\n\t\tshape && path.includes('select.')\n\t\t\t? ` / ${shape.type || ''}${\n\t\t\t\t\t'geo' in shape.props ? ' / ' + shape.props.geo : ''\n\t\t\t\t} / [${Vec.ToInt(editor.getPointInShapeSpace(shape, editor.inputs.currentPagePoint))}]`\n\t\t\t: ''\n\tconst ruler =\n\t\tpath.startsWith('select.') && !path.includes('.idle')\n\t\t\t? ` / [${Vec.ToInt(editor.inputs.originPagePoint)}] \u2192 [${Vec.ToInt(\n\t\t\t\t\teditor.inputs.currentPagePoint\n\t\t\t\t)}] = ${Vec.Dist(editor.inputs.originPagePoint, editor.inputs.currentPagePoint).toFixed(0)}`\n\t\t\t: ''\n\n\treturn <div className=\"tlui-debug-panel__current-state\">{`${path}${shapeInfo}${ruler}`}</div>\n})\n\nfunction FPS() {\n\tconst editor = useEditor()\n\tconst showFps = useValue('show_fps', () => debugFlags.showFps.get(), [debugFlags])\n\n\tconst fpsRef = useRef<HTMLDivElement>(null)\n\n\tuseEffect(() => {\n\t\tif (!showFps) return\n\n\t\tconst TICK_LENGTH = 250\n\t\tlet maxKnownFps = 0\n\t\tlet raf = -1\n\n\t\tlet start = performance.now()\n\t\tlet currentTickLength = 0\n\t\tlet framesInCurrentTick = 0\n\t\tlet isSlow = false\n\n\t\t// A \"tick\" is the amount of time between renders. Even though\n\t\t// we'll loop on every frame, we will only paint when the time\n\t\t// since the last paint is greater than the tick length.\n\n\t\t// When we paint, we'll calculate the FPS based on the number\n\t\t// of frames that we've seen since the last time we rendered,\n\t\t// and the actual time since the last render.\n\t\tfunction loop() {\n\t\t\t// Count the frame\n\t\t\tframesInCurrentTick++\n\n\t\t\t// Check if we should render\n\t\t\tcurrentTickLength = performance.now() - start\n\n\t\t\tif (currentTickLength > TICK_LENGTH) {\n\t\t\t\t// Calculate the FPS and paint it\n\t\t\t\tconst fps = Math.round(\n\t\t\t\t\tframesInCurrentTick * (TICK_LENGTH / currentTickLength) * (1000 / TICK_LENGTH)\n\t\t\t\t)\n\n\t\t\t\tif (fps > maxKnownFps) {\n\t\t\t\t\tmaxKnownFps = fps\n\t\t\t\t}\n\n\t\t\t\tconst slowFps = maxKnownFps * 0.75\n\t\t\t\tif ((fps < slowFps && !isSlow) || (fps >= slowFps && isSlow)) {\n\t\t\t\t\tisSlow = !isSlow\n\t\t\t\t}\n\n\t\t\t\tfpsRef.current!.innerHTML = `FPS ${fps.toString()}`\n\t\t\t\tfpsRef.current!.className =\n\t\t\t\t\t`tlui-debug-panel__fps` + (isSlow ? ` tlui-debug-panel__fps__slow` : ``)\n\n\t\t\t\t// Reset the values\n\t\t\t\tcurrentTickLength -= TICK_LENGTH\n\t\t\t\tframesInCurrentTick = 0\n\t\t\t\tstart = performance.now()\n\t\t\t}\n\n\t\t\traf = editor.timers.requestAnimationFrame(loop)\n\t\t}\n\n\t\tloop()\n\n\t\treturn () => {\n\t\t\tcancelAnimationFrame(raf)\n\t\t}\n\t}, [showFps, editor])\n\n\tif (!showFps) return null\n\n\treturn <div ref={fpsRef} />\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["DefaultDebugPanel", "CurrentState"]
|
|
7
7
|
}
|
|
@@ -26,29 +26,17 @@ var import_editor = require("@tldraw/editor");
|
|
|
26
26
|
var import_radix_ui = require("radix-ui");
|
|
27
27
|
var import_react = require("react");
|
|
28
28
|
var import_dialogs = require("../context/dialogs");
|
|
29
|
-
const TldrawUiDialog = ({
|
|
30
|
-
id,
|
|
31
|
-
component: ModalContent,
|
|
32
|
-
onClose,
|
|
33
|
-
preventBackgroundClose
|
|
34
|
-
}) => {
|
|
29
|
+
const TldrawUiDialog = ({ id, component: ModalContent, preventBackgroundClose }) => {
|
|
35
30
|
const { removeDialog } = (0, import_dialogs.useDialogs)();
|
|
36
31
|
const mouseDownInsideContentRef = (0, import_react.useRef)(false);
|
|
37
32
|
const container = (0, import_editor.useContainer)();
|
|
38
33
|
const handleOpenChange = (0, import_react.useCallback)(
|
|
39
34
|
(isOpen) => {
|
|
40
35
|
if (!isOpen) {
|
|
41
|
-
if (onClose) {
|
|
42
|
-
try {
|
|
43
|
-
onClose();
|
|
44
|
-
} catch (err) {
|
|
45
|
-
console.warn(err);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
36
|
removeDialog(id);
|
|
49
37
|
}
|
|
50
38
|
},
|
|
51
|
-
[id,
|
|
39
|
+
[id, removeDialog]
|
|
52
40
|
);
|
|
53
41
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_radix_ui.Dialog.Root, { onOpenChange: handleOpenChange, defaultOpen: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_radix_ui.Dialog.Portal, { container, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
54
42
|
import_radix_ui.Dialog.Overlay,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/ui/components/Dialogs.tsx"],
|
|
4
|
-
"sourcesContent": ["import { useContainer, useValue } from '@tldraw/editor'\nimport { Dialog as _Dialog } from 'radix-ui'\nimport { memo, useCallback, useRef } from 'react'\nimport { TLUiDialog, useDialogs } from '../context/dialogs'\n\n/** @internal */\nconst TldrawUiDialog = ({
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import { useContainer, useValue } from '@tldraw/editor'\nimport { Dialog as _Dialog } from 'radix-ui'\nimport { memo, useCallback, useRef } from 'react'\nimport { TLUiDialog, useDialogs } from '../context/dialogs'\n\n/** @internal */\nconst TldrawUiDialog = ({ id, component: ModalContent, preventBackgroundClose }: TLUiDialog) => {\n\tconst { removeDialog } = useDialogs()\n\tconst mouseDownInsideContentRef = useRef(false)\n\n\tconst container = useContainer()\n\n\tconst handleOpenChange = useCallback(\n\t\t(isOpen: boolean) => {\n\t\t\tif (!isOpen) {\n\t\t\t\tremoveDialog(id)\n\t\t\t}\n\t\t},\n\t\t[id, removeDialog]\n\t)\n\n\treturn (\n\t\t<_Dialog.Root onOpenChange={handleOpenChange} defaultOpen>\n\t\t\t<_Dialog.Portal container={container}>\n\t\t\t\t<_Dialog.Overlay\n\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\tclassName=\"tlui-dialog__overlay\"\n\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t// We pressed mouse down inside the content of the dialog then moved the mouse\n\t\t\t\t\t\t// outside it and let go of the mouse button. This should not close the dialog.\n\t\t\t\t\t\tif (mouseDownInsideContentRef.current) return\n\t\t\t\t\t\t// only close if the click is on the overlay itself, ignore bubbling clicks\n\t\t\t\t\t\tif (!preventBackgroundClose && e.target === e.currentTarget) handleOpenChange(false)\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<_Dialog.Content\n\t\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\t\tclassName=\"tlui-dialog__content\"\n\t\t\t\t\t\taria-describedby={undefined}\n\t\t\t\t\t\tonMouseDown={() => (mouseDownInsideContentRef.current = true)}\n\t\t\t\t\t\tonMouseUp={() => (mouseDownInsideContentRef.current = false)}\n\t\t\t\t\t\tonInteractOutside={(e) => {\n\t\t\t\t\t\t\tmouseDownInsideContentRef.current = false\n\t\t\t\t\t\t\tif (preventBackgroundClose) {\n\t\t\t\t\t\t\t\te.preventDefault()\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<ModalContent\n\t\t\t\t\t\t\tonClose={() => {\n\t\t\t\t\t\t\t\tmouseDownInsideContentRef.current = false\n\t\t\t\t\t\t\t\thandleOpenChange(false)\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</_Dialog.Content>\n\t\t\t\t</_Dialog.Overlay>\n\t\t\t</_Dialog.Portal>\n\t\t</_Dialog.Root>\n\t)\n}\n\n/** @public @react */\nexport const DefaultDialogs = memo(function DefaultDialogs() {\n\tconst { dialogs } = useDialogs()\n\tconst dialogsArray = useValue('dialogs', () => dialogs.get(), [dialogs])\n\treturn dialogsArray.map((dialog) => <TldrawUiDialog key={dialog.id} {...dialog} />)\n})\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgDM;AAhDN,oBAAuC;AACvC,sBAAkC;AAClC,mBAA0C;AAC1C,qBAAuC;AAGvC,MAAM,iBAAiB,CAAC,EAAE,IAAI,WAAW,cAAc,uBAAuB,MAAkB;AAC/F,QAAM,EAAE,aAAa,QAAI,2BAAW;AACpC,QAAM,gCAA4B,qBAAO,KAAK;AAE9C,QAAM,gBAAY,4BAAa;AAE/B,QAAM,uBAAmB;AAAA,IACxB,CAAC,WAAoB;AACpB,UAAI,CAAC,QAAQ;AACZ,qBAAa,EAAE;AAAA,MAChB;AAAA,IACD;AAAA,IACA,CAAC,IAAI,YAAY;AAAA,EAClB;AAEA,SACC,4CAAC,gBAAAA,OAAQ,MAAR,EAAa,cAAc,kBAAkB,aAAW,MACxD,sDAAC,gBAAAA,OAAQ,QAAR,EAAe,WACf;AAAA,IAAC,gBAAAA,OAAQ;AAAA,IAAR;AAAA,MACA,KAAI;AAAA,MACJ,WAAU;AAAA,MACV,SAAS,CAAC,MAAM;AAGf,YAAI,0BAA0B,QAAS;AAEvC,YAAI,CAAC,0BAA0B,EAAE,WAAW,EAAE,cAAe,kBAAiB,KAAK;AAAA,MACpF;AAAA,MAEA;AAAA,QAAC,gBAAAA,OAAQ;AAAA,QAAR;AAAA,UACA,KAAI;AAAA,UACJ,WAAU;AAAA,UACV,oBAAkB;AAAA,UAClB,aAAa,MAAO,0BAA0B,UAAU;AAAA,UACxD,WAAW,MAAO,0BAA0B,UAAU;AAAA,UACtD,mBAAmB,CAAC,MAAM;AACzB,sCAA0B,UAAU;AACpC,gBAAI,wBAAwB;AAC3B,gBAAE,eAAe;AAAA,YAClB;AAAA,UACD;AAAA,UAEA;AAAA,YAAC;AAAA;AAAA,cACA,SAAS,MAAM;AACd,0CAA0B,UAAU;AACpC,iCAAiB,KAAK;AAAA,cACvB;AAAA;AAAA,UACD;AAAA;AAAA,MACD;AAAA;AAAA,EACD,GACD,GACD;AAEF;AAGO,MAAM,qBAAiB,mBAAK,SAASC,kBAAiB;AAC5D,QAAM,EAAE,QAAQ,QAAI,2BAAW;AAC/B,QAAM,mBAAe,wBAAS,WAAW,MAAM,QAAQ,IAAI,GAAG,CAAC,OAAO,CAAC;AACvE,SAAO,aAAa,IAAI,CAAC,WAAW,4CAAC,kBAAgC,GAAG,UAAf,OAAO,EAAgB,CAAE;AACnF,CAAC;",
|
|
6
6
|
"names": ["_Dialog", "DefaultDialogs"]
|
|
7
7
|
}
|
|
@@ -259,6 +259,7 @@ const DefaultPageMenu = (0, import_react.memo)(function DefaultPageMenu2() {
|
|
|
259
259
|
},
|
|
260
260
|
[editor, trackEvent]
|
|
261
261
|
);
|
|
262
|
+
const shouldUseWindowPrompt = breakpoint < import_constants.PORTRAIT_BREAKPOINT.TABLET_SM && isCoarsePointer;
|
|
262
263
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_TldrawUiPopover.TldrawUiPopover, { id: "pages", onOpenChange, open: isOpen, children: [
|
|
263
264
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiPopover.TldrawUiPopoverTrigger, { "data-testid": "main.page-menu", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
264
265
|
import_TldrawUiButton.TldrawUiButton,
|
|
@@ -347,7 +348,7 @@ const DefaultPageMenu = (0, import_react.memo)(function DefaultPageMenu2() {
|
|
|
347
348
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiButtonIcon.TldrawUiButtonIcon, { icon: "drag-handle-dots" })
|
|
348
349
|
}
|
|
349
350
|
),
|
|
350
|
-
|
|
351
|
+
shouldUseWindowPrompt ? (
|
|
351
352
|
// sigh, this is a workaround for iOS Safari
|
|
352
353
|
// because the device and the radix popover seem
|
|
353
354
|
// to be fighting over scroll position. Nothing
|
|
@@ -358,7 +359,7 @@ const DefaultPageMenu = (0, import_react.memo)(function DefaultPageMenu2() {
|
|
|
358
359
|
type: "normal",
|
|
359
360
|
className: "tlui-page-menu__item__button",
|
|
360
361
|
onClick: () => {
|
|
361
|
-
const name = window.prompt("
|
|
362
|
+
const name = window.prompt(msg("action.rename"), page.name);
|
|
362
363
|
if (name && name !== page.name) {
|
|
363
364
|
renamePage(page.id, name);
|
|
364
365
|
}
|
|
@@ -431,8 +432,8 @@ const DefaultPageMenu = (0, import_react.memo)(function DefaultPageMenu2() {
|
|
|
431
432
|
item: page,
|
|
432
433
|
listSize: pages.length,
|
|
433
434
|
onRename: () => {
|
|
434
|
-
if (
|
|
435
|
-
const name = window.prompt("
|
|
435
|
+
if (shouldUseWindowPrompt) {
|
|
436
|
+
const name = window.prompt(msg("action.rename"), page.name);
|
|
436
437
|
if (name && name !== page.name) {
|
|
437
438
|
renamePage(page.id, name);
|
|
438
439
|
}
|
|
@@ -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
|
}
|
|
@@ -53,7 +53,7 @@ function LinkEditor({ textEditor, value: initialValue, onClose }) {
|
|
|
53
53
|
};
|
|
54
54
|
const handleVisitLink = () => {
|
|
55
55
|
trackEvent("rich-text", { operation: "link-visit", source });
|
|
56
|
-
|
|
56
|
+
(0, import_editor.openWindow)(linkifiedValue, "_blank");
|
|
57
57
|
onClose();
|
|
58
58
|
};
|
|
59
59
|
const handleRemoveLink = () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/ui/components/Toolbar/LinkEditor.tsx"],
|
|
4
|
-
"sourcesContent": ["import { preventDefault, TiptapEditor, useEditor } from '@tldraw/editor'\nimport { useEffect, useRef, useState } from 'react'\nimport { useUiEvents } from '../../context/events'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiInput } from '../primitives/TldrawUiInput'\n\n/** @public */\nexport interface LinkEditorProps {\n\ttextEditor: TiptapEditor\n\tvalue: string\n\tonClose(): void\n}\n\n/** @public @react */\nexport function LinkEditor({ textEditor, value: initialValue, onClose }: LinkEditorProps) {\n\tconst editor = useEditor()\n\tconst [value, setValue] = useState(initialValue)\n\tconst msg = useTranslation()\n\tconst ref = useRef<HTMLInputElement>(null)\n\tconst trackEvent = useUiEvents()\n\tconst source = 'rich-text-menu'\n\tconst linkifiedValue = value.startsWith('http') ? value : `https://${value}`\n\n\tconst handleValueChange = (value: string) => setValue(value)\n\n\tconst handleLinkComplete = (link: string) => {\n\t\ttrackEvent('rich-text', { operation: 'link-edit', source })\n\t\tif (!link.startsWith('http://') && !link.startsWith('https://')) {\n\t\t\tlink = `https://${link}`\n\t\t}\n\n\t\ttextEditor.chain().setLink({ href: link }).run()\n\t\t// N.B. We shouldn't focus() on mobile because it causes the\n\t\t// Return key to replace the link with a newline :facepalm:\n\t\tif (editor.getInstanceState().isCoarsePointer) {\n\t\t\ttextEditor.commands.blur()\n\t\t} else {\n\t\t\ttextEditor.commands.focus()\n\t\t}\n\t\tonClose()\n\t}\n\n\tconst handleVisitLink = () => {\n\t\ttrackEvent('rich-text', { operation: 'link-visit', source })\n\t\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAmEE;AAnEF,
|
|
4
|
+
"sourcesContent": ["import { openWindow, preventDefault, TiptapEditor, useEditor } from '@tldraw/editor'\nimport { useEffect, useRef, useState } from 'react'\nimport { useUiEvents } from '../../context/events'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiInput } from '../primitives/TldrawUiInput'\n\n/** @public */\nexport interface LinkEditorProps {\n\ttextEditor: TiptapEditor\n\tvalue: string\n\tonClose(): void\n}\n\n/** @public @react */\nexport function LinkEditor({ textEditor, value: initialValue, onClose }: LinkEditorProps) {\n\tconst editor = useEditor()\n\tconst [value, setValue] = useState(initialValue)\n\tconst msg = useTranslation()\n\tconst ref = useRef<HTMLInputElement>(null)\n\tconst trackEvent = useUiEvents()\n\tconst source = 'rich-text-menu'\n\tconst linkifiedValue = value.startsWith('http') ? value : `https://${value}`\n\n\tconst handleValueChange = (value: string) => setValue(value)\n\n\tconst handleLinkComplete = (link: string) => {\n\t\ttrackEvent('rich-text', { operation: 'link-edit', source })\n\t\tif (!link.startsWith('http://') && !link.startsWith('https://')) {\n\t\t\tlink = `https://${link}`\n\t\t}\n\n\t\ttextEditor.chain().setLink({ href: link }).run()\n\t\t// N.B. We shouldn't focus() on mobile because it causes the\n\t\t// Return key to replace the link with a newline :facepalm:\n\t\tif (editor.getInstanceState().isCoarsePointer) {\n\t\t\ttextEditor.commands.blur()\n\t\t} else {\n\t\t\ttextEditor.commands.focus()\n\t\t}\n\t\tonClose()\n\t}\n\n\tconst handleVisitLink = () => {\n\t\ttrackEvent('rich-text', { operation: 'link-visit', source })\n\t\topenWindow(linkifiedValue, '_blank')\n\t\tonClose()\n\t}\n\n\tconst handleRemoveLink = () => {\n\t\ttrackEvent('rich-text', { operation: 'link-remove', source })\n\t\ttextEditor.chain().unsetLink().focus().run()\n\t\tonClose()\n\t}\n\n\tconst handleLinkCancel = () => onClose()\n\n\tuseEffect(() => {\n\t\tref.current?.focus()\n\t}, [value])\n\n\tuseEffect(() => {\n\t\tsetValue(initialValue)\n\t}, [initialValue])\n\n\treturn (\n\t\t<>\n\t\t\t<TldrawUiInput\n\t\t\t\tref={ref}\n\t\t\t\tdata-testid=\"rich-text.link-input\"\n\t\t\t\tclassName=\"tlui-rich-text__toolbar-link-input\"\n\t\t\t\tvalue={value}\n\t\t\t\tonValueChange={handleValueChange}\n\t\t\t\tonComplete={handleLinkComplete}\n\t\t\t\tonCancel={handleLinkCancel}\n\t\t\t\tplaceholder=\"example.com\"\n\t\t\t\taria-label=\"example.com\"\n\t\t\t/>\n\t\t\t<TldrawUiButton\n\t\t\t\tclassName=\"tlui-rich-text__toolbar-link-visit\"\n\t\t\t\ttitle={msg('tool.rich-text-link-visit')}\n\t\t\t\ttype=\"icon\"\n\t\t\t\tonPointerDown={preventDefault}\n\t\t\t\tonClick={handleVisitLink}\n\t\t\t\tdisabled={!value}\n\t\t\t>\n\t\t\t\t<TldrawUiButtonIcon small icon=\"external-link\" />\n\t\t\t</TldrawUiButton>\n\t\t\t<TldrawUiButton\n\t\t\t\tclassName=\"tlui-rich-text__toolbar-link-remove\"\n\t\t\t\ttitle={msg('tool.rich-text-link-remove')}\n\t\t\t\tdata-testid=\"rich-text.link-remove\"\n\t\t\t\ttype=\"icon\"\n\t\t\t\tonPointerDown={preventDefault}\n\t\t\t\tonClick={handleRemoveLink}\n\t\t\t>\n\t\t\t\t<TldrawUiButtonIcon small icon=\"trash\" />\n\t\t\t</TldrawUiButton>\n\t\t</>\n\t)\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAmEE;AAnEF,oBAAoE;AACpE,mBAA4C;AAC5C,oBAA4B;AAC5B,4BAA+B;AAC/B,4BAA+B;AAC/B,gCAAmC;AACnC,2BAA8B;AAUvB,SAAS,WAAW,EAAE,YAAY,OAAO,cAAc,QAAQ,GAAoB;AACzF,QAAM,aAAS,yBAAU;AACzB,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAS,YAAY;AAC/C,QAAM,UAAM,sCAAe;AAC3B,QAAM,UAAM,qBAAyB,IAAI;AACzC,QAAM,iBAAa,2BAAY;AAC/B,QAAM,SAAS;AACf,QAAM,iBAAiB,MAAM,WAAW,MAAM,IAAI,QAAQ,WAAW,KAAK;AAE1E,QAAM,oBAAoB,CAACA,WAAkB,SAASA,MAAK;AAE3D,QAAM,qBAAqB,CAAC,SAAiB;AAC5C,eAAW,aAAa,EAAE,WAAW,aAAa,OAAO,CAAC;AAC1D,QAAI,CAAC,KAAK,WAAW,SAAS,KAAK,CAAC,KAAK,WAAW,UAAU,GAAG;AAChE,aAAO,WAAW,IAAI;AAAA,IACvB;AAEA,eAAW,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC,EAAE,IAAI;AAG/C,QAAI,OAAO,iBAAiB,EAAE,iBAAiB;AAC9C,iBAAW,SAAS,KAAK;AAAA,IAC1B,OAAO;AACN,iBAAW,SAAS,MAAM;AAAA,IAC3B;AACA,YAAQ;AAAA,EACT;AAEA,QAAM,kBAAkB,MAAM;AAC7B,eAAW,aAAa,EAAE,WAAW,cAAc,OAAO,CAAC;AAC3D,kCAAW,gBAAgB,QAAQ;AACnC,YAAQ;AAAA,EACT;AAEA,QAAM,mBAAmB,MAAM;AAC9B,eAAW,aAAa,EAAE,WAAW,eAAe,OAAO,CAAC;AAC5D,eAAW,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI;AAC3C,YAAQ;AAAA,EACT;AAEA,QAAM,mBAAmB,MAAM,QAAQ;AAEvC,8BAAU,MAAM;AACf,QAAI,SAAS,MAAM;AAAA,EACpB,GAAG,CAAC,KAAK,CAAC;AAEV,8BAAU,MAAM;AACf,aAAS,YAAY;AAAA,EACtB,GAAG,CAAC,YAAY,CAAC;AAEjB,SACC,4EACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACA;AAAA,QACA,eAAY;AAAA,QACZ,WAAU;AAAA,QACV;AAAA,QACA,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,aAAY;AAAA,QACZ,cAAW;AAAA;AAAA,IACZ;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACA,WAAU;AAAA,QACV,OAAO,IAAI,2BAA2B;AAAA,QACtC,MAAK;AAAA,QACL,eAAe;AAAA,QACf,SAAS;AAAA,QACT,UAAU,CAAC;AAAA,QAEX,sDAAC,gDAAmB,OAAK,MAAC,MAAK,iBAAgB;AAAA;AAAA,IAChD;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACA,WAAU;AAAA,QACV,OAAO,IAAI,4BAA4B;AAAA,QACvC,eAAY;AAAA,QACZ,MAAK;AAAA,QACL,eAAe;AAAA,QACf,SAAS;AAAA,QAET,sDAAC,gDAAmB,OAAK,MAAC,MAAK,SAAQ;AAAA;AAAA,IACxC;AAAA,KACD;AAEF;",
|
|
6
6
|
"names": ["value"]
|
|
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
|
}
|
|
@@ -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",
|