tldraw 4.2.0-next.3abbdad51d2e → 4.2.0-next.67908ea044c6

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.
Files changed (102) hide show
  1. package/dist-cjs/index.d.ts +3 -2
  2. package/dist-cjs/index.js +1 -1
  3. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js +63 -36
  4. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js.map +2 -2
  5. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +3 -3
  6. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  7. package/dist-cjs/lib/shapes/shared/RichTextLabel.js +1 -1
  8. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
  9. package/dist-cjs/lib/shapes/shared/ShapeFill.js +3 -0
  10. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  11. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +14 -6
  12. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  13. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +2 -2
  14. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  15. package/dist-cjs/lib/ui/components/DefaultDebugPanel.js +1 -1
  16. package/dist-cjs/lib/ui/components/DefaultDebugPanel.js.map +2 -2
  17. package/dist-cjs/lib/ui/components/Dialogs.js +2 -14
  18. package/dist-cjs/lib/ui/components/Dialogs.js.map +2 -2
  19. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +5 -4
  20. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  21. package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.js +2 -1
  22. package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.js.map +2 -2
  23. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +1 -1
  24. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
  25. package/dist-cjs/lib/ui/components/primitives/Button/TldrawUiButton.js +2 -2
  26. package/dist-cjs/lib/ui/components/primitives/Button/TldrawUiButton.js.map +2 -2
  27. package/dist-cjs/lib/ui/context/actions.js +16 -0
  28. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  29. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  30. package/dist-cjs/lib/ui/getLocalFiles.js +18 -3
  31. package/dist-cjs/lib/ui/getLocalFiles.js.map +2 -2
  32. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +18 -16
  33. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +3 -3
  34. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  35. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +1 -0
  36. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  37. package/dist-cjs/lib/ui/hooks/useTranslation/useTranslation.js +1 -0
  38. package/dist-cjs/lib/ui/hooks/useTranslation/useTranslation.js.map +2 -2
  39. package/dist-cjs/lib/ui/version.js +3 -3
  40. package/dist-cjs/lib/ui/version.js.map +1 -1
  41. package/dist-esm/index.d.mts +3 -2
  42. package/dist-esm/index.mjs +1 -1
  43. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs +65 -38
  44. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs.map +2 -2
  45. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -5
  46. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  47. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +2 -1
  48. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  49. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +3 -0
  50. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  51. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +14 -6
  52. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  53. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +2 -2
  54. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  55. package/dist-esm/lib/ui/components/DefaultDebugPanel.mjs +1 -1
  56. package/dist-esm/lib/ui/components/DefaultDebugPanel.mjs.map +2 -2
  57. package/dist-esm/lib/ui/components/Dialogs.mjs +2 -14
  58. package/dist-esm/lib/ui/components/Dialogs.mjs.map +2 -2
  59. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +5 -5
  60. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
  61. package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.mjs +2 -1
  62. package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.mjs.map +2 -2
  63. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +2 -2
  64. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
  65. package/dist-esm/lib/ui/components/primitives/Button/TldrawUiButton.mjs +2 -2
  66. package/dist-esm/lib/ui/components/primitives/Button/TldrawUiButton.mjs.map +2 -2
  67. package/dist-esm/lib/ui/context/actions.mjs +16 -0
  68. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  69. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  70. package/dist-esm/lib/ui/getLocalFiles.mjs +18 -3
  71. package/dist-esm/lib/ui/getLocalFiles.mjs.map +2 -2
  72. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +18 -16
  73. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +3 -3
  74. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +1 -0
  75. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  76. package/dist-esm/lib/ui/hooks/useTranslation/useTranslation.mjs +1 -0
  77. package/dist-esm/lib/ui/hooks/useTranslation/useTranslation.mjs.map +2 -2
  78. package/dist-esm/lib/ui/version.mjs +3 -3
  79. package/dist-esm/lib/ui/version.mjs.map +1 -1
  80. package/package.json +3 -3
  81. package/src/lib/shapes/frame/components/FrameLabelInput.tsx +48 -24
  82. package/src/lib/shapes/note/NoteShapeUtil.tsx +6 -5
  83. package/src/lib/shapes/shared/RichTextLabel.tsx +2 -1
  84. package/src/lib/shapes/shared/ShapeFill.tsx +3 -0
  85. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +19 -8
  86. package/src/lib/tools/SelectTool/childStates/Idle.ts +2 -2
  87. package/src/lib/ui/components/DefaultDebugPanel.tsx +1 -1
  88. package/src/lib/ui/components/Dialogs.tsx +2 -14
  89. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +6 -5
  90. package/src/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.tsx +4 -1
  91. package/src/lib/ui/components/Toolbar/LinkEditor.tsx +2 -2
  92. package/src/lib/ui/components/primitives/Button/TldrawUiButton.tsx +3 -2
  93. package/src/lib/ui/context/actions.tsx +16 -0
  94. package/src/lib/ui/context/events.tsx +1 -0
  95. package/src/lib/ui/getLocalFiles.ts +20 -3
  96. package/src/lib/ui/hooks/useClipboardEvents.ts +12 -9
  97. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +1 -0
  98. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +1 -0
  99. package/src/lib/ui/hooks/useTranslation/useTranslation.tsx +2 -1
  100. package/src/lib/ui/version.ts +3 -3
  101. package/src/test/TldrawEditor.test.tsx +74 -29
  102. package/src/test/customSnapping.test.tsx +185 -0
@@ -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;AA4HI;AA5HJ,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;AAC3C,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,SAAS,MAAM,KAAK;AAChD,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;",
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
- window.open(linkifiedValue, "_blank", "noopener, noreferrer");
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\twindow.open(linkifiedValue, '_blank', 'noopener, noreferrer')\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,oBAAwD;AACxD,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,WAAO,KAAK,gBAAgB,UAAU,sBAAsB;AAC5D,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;",
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=\"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;AAyBG;AAzBH,wBAAuB;AACvB,YAAuB;AASvB,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,UAAU,GAAG,MAAM,GAAG,KAAK;AACpE,WACC;AAAA,MAAC;AAAA;AAAA,QACA;AAAA,QACA,MAAK;AAAA,QACL,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;",
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",