tldraw 3.16.0-canary.e4220f725a90 → 3.16.0-canary.e455ab838b8f

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 (129) hide show
  1. package/dist-cjs/index.d.ts +11 -5
  2. package/dist-cjs/index.js +1 -1
  3. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +1 -1
  4. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  5. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js +8 -2
  6. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js.map +2 -2
  7. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +1 -1
  8. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
  9. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +2 -3
  10. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  11. package/dist-cjs/lib/shapes/text/PlainTextArea.js +2 -1
  12. package/dist-cjs/lib/shapes/text/PlainTextArea.js.map +2 -2
  13. package/dist-cjs/lib/ui/components/A11y.js +1 -1
  14. package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
  15. package/dist-cjs/lib/ui/components/LanguageMenu.js +1 -0
  16. package/dist-cjs/lib/ui/components/LanguageMenu.js.map +2 -2
  17. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +2 -1
  18. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
  19. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +1 -1
  20. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  21. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +11 -2
  22. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +2 -2
  23. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +3 -2
  24. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
  25. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +5 -4
  26. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
  27. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +1 -1
  28. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +2 -2
  29. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +6 -2
  30. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
  31. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
  32. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  33. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +3 -1
  34. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
  35. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +1 -0
  36. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  37. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +14 -2
  38. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  39. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js +3 -0
  40. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
  41. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +3 -3
  42. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  43. package/dist-cjs/lib/ui/context/actions.js +6 -0
  44. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  45. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +1 -1
  46. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
  47. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  48. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +1 -0
  49. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  50. package/dist-cjs/lib/ui/version.js +3 -3
  51. package/dist-cjs/lib/ui/version.js.map +1 -1
  52. package/dist-esm/index.d.mts +11 -5
  53. package/dist-esm/index.mjs +1 -1
  54. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +1 -2
  55. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  56. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs +9 -3
  57. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs.map +2 -2
  58. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +2 -2
  59. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  60. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +2 -4
  61. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  62. package/dist-esm/lib/shapes/text/PlainTextArea.mjs +3 -2
  63. package/dist-esm/lib/shapes/text/PlainTextArea.mjs.map +2 -2
  64. package/dist-esm/lib/ui/components/A11y.mjs +1 -2
  65. package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
  66. package/dist-esm/lib/ui/components/LanguageMenu.mjs +1 -0
  67. package/dist-esm/lib/ui/components/LanguageMenu.mjs.map +2 -2
  68. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +2 -1
  69. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
  70. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +1 -2
  71. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
  72. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +11 -2
  73. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +2 -2
  74. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +3 -2
  75. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
  76. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +5 -4
  77. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
  78. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +1 -1
  79. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +2 -2
  80. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +6 -2
  81. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
  82. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +1 -2
  83. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  84. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +3 -1
  85. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
  86. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +1 -0
  87. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  88. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +14 -2
  89. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  90. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs +3 -0
  91. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
  92. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +3 -3
  93. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  94. package/dist-esm/lib/ui/context/actions.mjs +6 -0
  95. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  96. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +1 -2
  97. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
  98. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +1 -0
  99. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  100. package/dist-esm/lib/ui/version.mjs +3 -3
  101. package/dist-esm/lib/ui/version.mjs.map +1 -1
  102. package/package.json +3 -3
  103. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +1 -2
  104. package/src/lib/shapes/frame/components/FrameLabelInput.tsx +10 -3
  105. package/src/lib/shapes/shared/HyperlinkButton.tsx +2 -2
  106. package/src/lib/shapes/shared/useEditablePlainText.ts +2 -5
  107. package/src/lib/shapes/text/PlainTextArea.tsx +3 -2
  108. package/src/lib/ui/components/A11y.tsx +1 -2
  109. package/src/lib/ui/components/LanguageMenu.tsx +1 -0
  110. package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +2 -1
  111. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +1 -2
  112. package/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx +9 -2
  113. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +4 -3
  114. package/src/lib/ui/components/Toolbar/LinkEditor.tsx +6 -5
  115. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +1 -1
  116. package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +9 -2
  117. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +1 -2
  118. package/src/lib/ui/components/primitives/TldrawUiInput.tsx +3 -0
  119. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +2 -1
  120. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +16 -2
  121. package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +4 -0
  122. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +3 -3
  123. package/src/lib/ui/context/actions.tsx +13 -0
  124. package/src/lib/ui/hooks/useClipboardEvents.ts +1 -2
  125. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +1 -0
  126. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +1 -0
  127. package/src/lib/ui/version.ts +3 -3
  128. package/src/lib/ui.css +4 -0
  129. package/tldraw.css +4 -0
@@ -3185,7 +3185,7 @@ export declare function TldrawUiMenuActionCheckboxItem({ actionId, ...rest }: TL
3185
3185
  export declare function TldrawUiMenuActionItem({ actionId, ...rest }: TLUiMenuActionItemProps): JSX_2.Element | null;
3186
3186
 
3187
3187
  /** @public @react */
3188
- export declare function TldrawUiMenuCheckboxItem<TranslationKey extends string = string, IconType extends string = string>({ id, kbd, label, readonlyOk, onSelect, toggle, disabled, checked, }: TLUiMenuCheckboxItemProps<TranslationKey, IconType>): JSX_2.Element | null;
3188
+ export declare function TldrawUiMenuCheckboxItem<TranslationKey extends string = string, IconType extends string = string>({ id, kbd, label, lang, readonlyOk, onSelect, toggle, disabled, checked, }: TLUiMenuCheckboxItemProps<TranslationKey, IconType>): JSX_2.Element | null;
3189
3189
 
3190
3190
  /** @public @react */
3191
3191
  export declare function TldrawUiMenuContextProvider({ type, sourceId, children, }: TLUiMenuContextProviderProps): JSX_2.Element;
@@ -3897,6 +3897,7 @@ export declare interface TLUiInputProps {
3897
3897
  shouldManuallyMaintainScrollPositionWhenFocused?: boolean;
3898
3898
  value?: string;
3899
3899
  'data-testid'?: string;
3900
+ 'aria-label'?: string;
3900
3901
  }
3901
3902
 
3902
3903
  /** @public */
@@ -3941,6 +3942,7 @@ export declare interface TLUiMenuCheckboxItemProps<TranslationKey extends string
3941
3942
  label?: {
3942
3943
  [key: string]: TranslationKey;
3943
3944
  } | TranslationKey;
3945
+ lang?: string;
3944
3946
  readonlyOk?: boolean;
3945
3947
  onSelect(source: TLUiEventSource): Promise<void> | void;
3946
3948
  toggle?: boolean;
@@ -4177,7 +4179,7 @@ export declare interface TLUiToolbarToggleItemProps extends React_3.HTMLAttribut
4177
4179
  className?: string;
4178
4180
  type: 'icon' | 'tool';
4179
4181
  value: string;
4180
- tooltip?: string;
4182
+ tooltip?: React_3.ReactNode;
4181
4183
  }
4182
4184
 
4183
4185
  /** @public */
@@ -4223,7 +4225,7 @@ export declare interface TLUiTranslation {
4223
4225
  export declare type TLUiTranslationContextType = TLUiTranslation;
4224
4226
 
4225
4227
  /** @public */
4226
- export declare type TLUiTranslationKey = 'a11y.adjust-shape-styles' | 'a11y.enlarge-shape' | 'a11y.enter-leave-container' | 'a11y.move-shape-faster' | 'a11y.move-shape' | 'a11y.multiple-shapes' | 'a11y.open-context-menu' | 'a11y.open-keyboard-shortcuts' | 'a11y.pan-camera' | 'a11y.repeat-shape' | 'a11y.rotate-shape-ccw-fine' | 'a11y.rotate-shape-ccw' | 'a11y.rotate-shape-cw-fine' | 'a11y.rotate-shape-cw' | 'a11y.select-shape-direction' | 'a11y.select-shape' | 'a11y.shape-image' | 'a11y.shape-index' | 'a11y.shape-video' | 'a11y.shrink-shape' | 'a11y.skip-to-main-content' | 'a11y.status' | 'action.align-bottom' | 'action.align-center-horizontal.short' | 'action.align-center-horizontal' | 'action.align-center-vertical.short' | 'action.align-center-vertical' | 'action.align-left' | 'action.align-right' | 'action.align-top' | 'action.back-to-content' | 'action.bring-forward' | 'action.bring-to-front' | 'action.convert-to-bookmark' | 'action.convert-to-embed' | 'action.copy-as-png.short' | 'action.copy-as-png' | 'action.copy-as-svg.short' | 'action.copy-as-svg' | 'action.copy' | 'action.cut' | 'action.delete' | 'action.distribute-horizontal.short' | 'action.distribute-horizontal' | 'action.distribute-vertical.short' | 'action.distribute-vertical' | 'action.download-original' | 'action.duplicate' | 'action.edit-link' | 'action.exit-pen-mode' | 'action.export-all-as-png.short' | 'action.export-all-as-png' | 'action.export-all-as-svg.short' | 'action.export-all-as-svg' | 'action.export-as-png.short' | 'action.export-as-png' | 'action.export-as-svg.short' | 'action.export-as-svg' | 'action.fit-frame-to-content' | 'action.flatten-to-image' | 'action.flip-horizontal.short' | 'action.flip-horizontal' | 'action.flip-vertical.short' | 'action.flip-vertical' | 'action.fork-project-on-tldraw' | 'action.fork-project' | 'action.group' | 'action.insert-embed' | 'action.insert-media' | 'action.leave-shared-project' | 'action.new-project' | 'action.new-shared-project' | 'action.open-cursor-chat' | 'action.open-embed-link' | 'action.open-file' | 'action.open-kbd-shortcuts' | 'action.pack' | 'action.paste-error-description' | 'action.paste-error-title' | 'action.paste' | 'action.print' | 'action.redo' | 'action.remove-frame' | 'action.rename' | 'action.rotate-ccw' | 'action.rotate-cw' | 'action.save-copy' | 'action.select-all' | 'action.select-none' | 'action.send-backward' | 'action.send-to-back' | 'action.share-project' | 'action.stack-horizontal.short' | 'action.stack-horizontal' | 'action.stack-vertical.short' | 'action.stack-vertical' | 'action.stop-following' | 'action.stretch-horizontal.short' | 'action.stretch-horizontal' | 'action.stretch-vertical.short' | 'action.stretch-vertical' | 'action.toggle-auto-size' | 'action.toggle-dark-mode.menu' | 'action.toggle-dark-mode' | 'action.toggle-debug-mode.menu' | 'action.toggle-debug-mode' | 'action.toggle-dynamic-size-mode.menu' | 'action.toggle-dynamic-size-mode' | 'action.toggle-edge-scrolling.menu' | 'action.toggle-edge-scrolling' | 'action.toggle-focus-mode.menu' | 'action.toggle-focus-mode' | 'action.toggle-grid.menu' | 'action.toggle-grid' | 'action.toggle-keyboard-shortcuts.menu' | 'action.toggle-keyboard-shortcuts' | 'action.toggle-lock' | 'action.toggle-paste-at-cursor.menu' | 'action.toggle-paste-at-cursor' | 'action.toggle-reduce-motion.menu' | 'action.toggle-reduce-motion' | 'action.toggle-snap-mode.menu' | 'action.toggle-snap-mode' | 'action.toggle-tool-lock.menu' | 'action.toggle-tool-lock' | 'action.toggle-transparent.context-menu' | 'action.toggle-transparent.menu' | 'action.toggle-transparent' | 'action.toggle-ui-labels.menu' | 'action.toggle-ui-labels' | 'action.toggle-wrap-mode.menu' | 'action.toggle-wrap-mode' | 'action.undo' | 'action.ungroup' | 'action.unlock-all' | 'action.zoom-in' | 'action.zoom-out' | 'action.zoom-to-100' | 'action.zoom-to-fit' | 'action.zoom-to-selection' | 'actions-menu.title' | 'align-style.end' | 'align-style.justify' | 'align-style.middle' | 'align-style.start' | 'app.loading' | 'arrow-kind-style.arc' | 'arrow-kind-style.elbow' | 'arrowheadEnd-style.arrow' | 'arrowheadEnd-style.bar' | 'arrowheadEnd-style.diamond' | 'arrowheadEnd-style.dot' | 'arrowheadEnd-style.inverted' | 'arrowheadEnd-style.none' | 'arrowheadEnd-style.pipe' | 'arrowheadEnd-style.square' | 'arrowheadEnd-style.triangle' | 'arrowheadStart-style.arrow' | 'arrowheadStart-style.bar' | 'arrowheadStart-style.diamond' | 'arrowheadStart-style.dot' | 'arrowheadStart-style.inverted' | 'arrowheadStart-style.none' | 'arrowheadStart-style.pipe' | 'arrowheadStart-style.square' | 'arrowheadStart-style.triangle' | 'assets.files.amount-too-many' | 'assets.files.maximum-size' | 'assets.files.size-too-big' | 'assets.files.type-not-allowed' | 'assets.files.upload-failed' | 'assets.url.failed' | 'color-style.black' | 'color-style.blue' | 'color-style.green' | 'color-style.grey' | 'color-style.light-blue' | 'color-style.light-green' | 'color-style.light-red' | 'color-style.light-violet' | 'color-style.orange' | 'color-style.red' | 'color-style.violet' | 'color-style.white' | 'color-style.yellow' | 'context-menu.arrange' | 'context-menu.copy-as' | 'context-menu.edit' | 'context-menu.export-all-as' | 'context-menu.export-as' | 'context-menu.move-to-page' | 'context-menu.reorder' | 'context-menu.title' | 'context.pages.new-page' | 'cursor-chat.type-to-chat' | 'dash-style.dashed' | 'dash-style.dotted' | 'dash-style.draw' | 'dash-style.solid' | 'document-name-menu.copy-link' | 'document.default-name' | 'edit-link-dialog.cancel' | 'edit-link-dialog.clear' | 'edit-link-dialog.detail' | 'edit-link-dialog.external-link' | 'edit-link-dialog.invalid-url' | 'edit-link-dialog.save' | 'edit-link-dialog.title' | 'edit-link-dialog.url' | 'embed-dialog.back' | 'embed-dialog.cancel' | 'embed-dialog.create' | 'embed-dialog.instruction' | 'embed-dialog.invalid-url' | 'embed-dialog.title' | 'embed-dialog.url' | 'file-system.confirm-clear.cancel' | 'file-system.confirm-clear.continue' | 'file-system.confirm-clear.description' | 'file-system.confirm-clear.dont-show-again' | 'file-system.confirm-clear.title' | 'file-system.confirm-open.cancel' | 'file-system.confirm-open.description' | 'file-system.confirm-open.dont-show-again' | 'file-system.confirm-open.open' | 'file-system.confirm-open.title' | 'file-system.file-open-error.file-format-version-too-new' | 'file-system.file-open-error.generic-corrupted-file' | 'file-system.file-open-error.not-a-tldraw-file' | 'file-system.file-open-error.title' | 'file-system.shared-document-file-open-error.description' | 'file-system.shared-document-file-open-error.title' | 'fill-style.fill' | 'fill-style.none' | 'fill-style.pattern' | 'fill-style.semi' | 'fill-style.solid' | 'focus-mode.toggle-focus-mode' | 'font-style.draw' | 'font-style.mono' | 'font-style.sans' | 'font-style.serif' | 'geo-style.arrow-down' | 'geo-style.arrow-left' | 'geo-style.arrow-right' | 'geo-style.arrow-up' | 'geo-style.check-box' | 'geo-style.cloud' | 'geo-style.diamond' | 'geo-style.ellipse' | 'geo-style.heart' | 'geo-style.hexagon' | 'geo-style.octagon' | 'geo-style.oval' | 'geo-style.pentagon' | 'geo-style.rectangle' | 'geo-style.rhombus-2' | 'geo-style.rhombus' | 'geo-style.star' | 'geo-style.trapezoid' | 'geo-style.triangle' | 'geo-style.x-box' | 'handle.crop.bottom-left' | 'handle.crop.bottom-right' | 'handle.crop.bottom' | 'handle.crop.left' | 'handle.crop.right' | 'handle.crop.top-left' | 'handle.crop.top-right' | 'handle.crop.top' | 'handle.resize-bottom-left' | 'handle.resize-bottom-right' | 'handle.resize-bottom' | 'handle.resize-left' | 'handle.resize-right' | 'handle.resize-top-left' | 'handle.resize-top-right' | 'handle.resize-top' | 'handle.rotate.bottom_left_rotate' | 'handle.rotate.bottom_right_rotate' | 'handle.rotate.mobile_rotate' | 'handle.rotate.top_left_rotate' | 'handle.rotate.top_right_rotate' | 'help-menu.about' | 'help-menu.discord' | 'help-menu.github' | 'help-menu.import-tldr-file' | 'help-menu.keyboard-shortcuts' | 'help-menu.privacy' | 'help-menu.terms' | 'help-menu.title' | 'help-menu.twitter' | 'menu.accessibility' | 'menu.copy-as' | 'menu.edit' | 'menu.export-as' | 'menu.file' | 'menu.language' | 'menu.preferences' | 'menu.theme' | 'menu.title' | 'menu.view' | 'navigation-zone.minimap' | 'navigation-zone.title' | 'navigation-zone.toggle-minimap' | 'navigation-zone.zoom' | 'opacity-style.0.1' | 'opacity-style.0.25' | 'opacity-style.0.5' | 'opacity-style.0.75' | 'opacity-style.1' | 'page-menu.create-new-page' | 'page-menu.edit-done' | 'page-menu.edit-start' | 'page-menu.go-to-page' | 'page-menu.max-page-count-reached' | 'page-menu.new-page-initial-name' | 'page-menu.submenu.delete' | 'page-menu.submenu.duplicate-page' | 'page-menu.submenu.move-down' | 'page-menu.submenu.move-up' | 'page-menu.submenu.rename' | 'page-menu.submenu.title' | 'page-menu.title' | 'people-menu.anonymous-user' | 'people-menu.avatar-color' | 'people-menu.change-color' | 'people-menu.change-name' | 'people-menu.follow' | 'people-menu.following' | 'people-menu.invite' | 'people-menu.leading' | 'people-menu.title' | 'people-menu.user' | 'share-menu.copied' | 'share-menu.copy-link-note' | 'share-menu.copy-link' | 'share-menu.copy-readonly-link-note' | 'share-menu.copy-readonly-link' | 'share-menu.create-snapshot-link' | 'share-menu.creating-project' | 'share-menu.fork-note' | 'share-menu.offline-note' | 'share-menu.project-too-large' | 'share-menu.save-note' | 'share-menu.share-project' | 'share-menu.snapshot-link-note' | 'share-menu.title' | 'share-menu.upload-failed' | 'sharing.confirm-leave.cancel' | 'sharing.confirm-leave.description' | 'sharing.confirm-leave.dont-show-again' | 'sharing.confirm-leave.leave' | 'sharing.confirm-leave.title' | 'shortcuts-dialog.a11y' | 'shortcuts-dialog.collaboration' | 'shortcuts-dialog.edit' | 'shortcuts-dialog.file' | 'shortcuts-dialog.preferences' | 'shortcuts-dialog.text-formatting' | 'shortcuts-dialog.title' | 'shortcuts-dialog.tools' | 'shortcuts-dialog.transform' | 'shortcuts-dialog.view' | 'size-style.l' | 'size-style.m' | 'size-style.s' | 'size-style.xl' | 'spline-style.cubic' | 'spline-style.line' | 'status.offline' | 'style-panel.align' | 'style-panel.arrow-kind' | 'style-panel.arrowhead-end' | 'style-panel.arrowhead-start' | 'style-panel.arrowheads' | 'style-panel.color' | 'style-panel.dash' | 'style-panel.fill' | 'style-panel.font' | 'style-panel.geo' | 'style-panel.label-align' | 'style-panel.mixed' | 'style-panel.opacity' | 'style-panel.position' | 'style-panel.size' | 'style-panel.spline' | 'style-panel.title' | 'style-panel.vertical-align' | 'theme.dark' | 'theme.light' | 'theme.system' | 'toast.close' | 'toast.error.copy-fail.desc' | 'toast.error.copy-fail.title' | 'toast.error.export-fail.desc' | 'toast.error.export-fail.title' | 'toast.error' | 'toast.info' | 'toast.success' | 'toast.warning' | 'tool-panel.more' | 'tool-panel.title' | 'tool.arrow-down' | 'tool.arrow-left' | 'tool.arrow-right' | 'tool.arrow-up' | 'tool.arrow' | 'tool.aspect-ratio.circle' | 'tool.aspect-ratio.landscape' | 'tool.aspect-ratio.original' | 'tool.aspect-ratio.portrait' | 'tool.aspect-ratio.square' | 'tool.aspect-ratio.wide' | 'tool.aspect-ratio' | 'tool.bookmark' | 'tool.check-box' | 'tool.cloud' | 'tool.diamond' | 'tool.draw' | 'tool.ellipse' | 'tool.embed' | 'tool.eraser' | 'tool.flip-horz' | 'tool.flip-vert' | 'tool.frame' | 'tool.hand' | 'tool.heart' | 'tool.hexagon' | 'tool.highlight' | 'tool.image-crop-confirm' | 'tool.image-crop' | 'tool.image-toolbar-title' | 'tool.image-zoom' | 'tool.laser' | 'tool.line' | 'tool.media-alt-text-confirm' | 'tool.media-alt-text-desc' | 'tool.media-alt-text' | 'tool.media' | 'tool.note' | 'tool.octagon' | 'tool.oval' | 'tool.pentagon' | 'tool.pointer-down' | 'tool.rectangle' | 'tool.replace-media' | 'tool.rhombus' | 'tool.rich-text-bold' | 'tool.rich-text-bulletList' | 'tool.rich-text-code' | 'tool.rich-text-header' | 'tool.rich-text-highlight' | 'tool.rich-text-italic' | 'tool.rich-text-link-remove' | 'tool.rich-text-link-visit' | 'tool.rich-text-link' | 'tool.rich-text-orderedList' | 'tool.rich-text-strikethrough' | 'tool.rich-text-toolbar-title' | 'tool.rotate-cw' | 'tool.select' | 'tool.star' | 'tool.text' | 'tool.trapezoid' | 'tool.triangle' | 'tool.x-box' | 'ui.checked' | 'ui.close' | 'ui.unchecked' | 'verticalAlign-style.end' | 'verticalAlign-style.middle' | 'verticalAlign-style.start' | 'vscode.file-open.backup-failed' | 'vscode.file-open.backup-saved' | 'vscode.file-open.backup' | 'vscode.file-open.desc' | 'vscode.file-open.dont-show-again' | 'vscode.file-open.open';
4228
+ export declare type TLUiTranslationKey = 'a11y.adjust-shape-styles' | 'a11y.enlarge-shape' | 'a11y.enter-leave-container' | 'a11y.move-shape-faster' | 'a11y.move-shape' | 'a11y.multiple-shapes' | 'a11y.open-context-menu' | 'a11y.open-keyboard-shortcuts' | 'a11y.pan-camera' | 'a11y.repeat-shape' | 'a11y.rotate-shape-ccw-fine' | 'a11y.rotate-shape-ccw' | 'a11y.rotate-shape-cw-fine' | 'a11y.rotate-shape-cw' | 'a11y.select-shape-direction' | 'a11y.select-shape' | 'a11y.shape-image' | 'a11y.shape-index' | 'a11y.shape-video' | 'a11y.shrink-shape' | 'a11y.skip-to-main-content' | 'a11y.status' | 'action.align-bottom' | 'action.align-center-horizontal.short' | 'action.align-center-horizontal' | 'action.align-center-vertical.short' | 'action.align-center-vertical' | 'action.align-left' | 'action.align-right' | 'action.align-top' | 'action.back-to-content' | 'action.bring-forward' | 'action.bring-to-front' | 'action.convert-to-bookmark' | 'action.convert-to-embed' | 'action.copy-as-png.short' | 'action.copy-as-png' | 'action.copy-as-svg.short' | 'action.copy-as-svg' | 'action.copy' | 'action.cut' | 'action.delete' | 'action.distribute-horizontal.short' | 'action.distribute-horizontal' | 'action.distribute-vertical.short' | 'action.distribute-vertical' | 'action.download-original' | 'action.duplicate' | 'action.edit-link' | 'action.exit-pen-mode' | 'action.export-all-as-png.short' | 'action.export-all-as-png' | 'action.export-all-as-svg.short' | 'action.export-all-as-svg' | 'action.export-as-png.short' | 'action.export-as-png' | 'action.export-as-svg.short' | 'action.export-as-svg' | 'action.fit-frame-to-content' | 'action.flatten-to-image' | 'action.flip-horizontal.short' | 'action.flip-horizontal' | 'action.flip-vertical.short' | 'action.flip-vertical' | 'action.fork-project-on-tldraw' | 'action.fork-project' | 'action.group' | 'action.insert-embed' | 'action.insert-media' | 'action.leave-shared-project' | 'action.new-project' | 'action.new-shared-project' | 'action.open-cursor-chat' | 'action.open-embed-link' | 'action.open-file' | 'action.open-kbd-shortcuts' | 'action.pack' | 'action.paste-error-description' | 'action.paste-error-title' | 'action.paste' | 'action.print' | 'action.redo' | 'action.remove-frame' | 'action.rename' | 'action.rotate-ccw' | 'action.rotate-cw' | 'action.save-copy' | 'action.select-all' | 'action.select-none' | 'action.send-backward' | 'action.send-to-back' | 'action.share-project' | 'action.stack-horizontal.short' | 'action.stack-horizontal' | 'action.stack-vertical.short' | 'action.stack-vertical' | 'action.stop-following' | 'action.stretch-horizontal.short' | 'action.stretch-horizontal' | 'action.stretch-vertical.short' | 'action.stretch-vertical' | 'action.toggle-auto-size' | 'action.toggle-dark-mode.menu' | 'action.toggle-dark-mode' | 'action.toggle-debug-mode.menu' | 'action.toggle-debug-mode' | 'action.toggle-dynamic-size-mode.menu' | 'action.toggle-dynamic-size-mode' | 'action.toggle-edge-scrolling.menu' | 'action.toggle-edge-scrolling' | 'action.toggle-focus-mode.menu' | 'action.toggle-focus-mode' | 'action.toggle-grid.menu' | 'action.toggle-grid' | 'action.toggle-keyboard-shortcuts.menu' | 'action.toggle-keyboard-shortcuts' | 'action.toggle-lock' | 'action.toggle-paste-at-cursor.menu' | 'action.toggle-paste-at-cursor' | 'action.toggle-reduce-motion.menu' | 'action.toggle-reduce-motion' | 'action.toggle-snap-mode.menu' | 'action.toggle-snap-mode' | 'action.toggle-tool-lock.menu' | 'action.toggle-tool-lock' | 'action.toggle-transparent.context-menu' | 'action.toggle-transparent.menu' | 'action.toggle-transparent' | 'action.toggle-ui-labels.menu' | 'action.toggle-ui-labels' | 'action.toggle-wrap-mode.menu' | 'action.toggle-wrap-mode' | 'action.undo' | 'action.ungroup' | 'action.unlock-all' | 'action.zoom-in' | 'action.zoom-out' | 'action.zoom-to-100' | 'action.zoom-to-fit' | 'action.zoom-to-selection' | 'actions-menu.title' | 'align-style.end' | 'align-style.justify' | 'align-style.middle' | 'align-style.start' | 'app.loading' | 'arrow-kind-style.arc' | 'arrow-kind-style.elbow' | 'arrowheadEnd-style.arrow' | 'arrowheadEnd-style.bar' | 'arrowheadEnd-style.diamond' | 'arrowheadEnd-style.dot' | 'arrowheadEnd-style.inverted' | 'arrowheadEnd-style.none' | 'arrowheadEnd-style.pipe' | 'arrowheadEnd-style.square' | 'arrowheadEnd-style.triangle' | 'arrowheadStart-style.arrow' | 'arrowheadStart-style.bar' | 'arrowheadStart-style.diamond' | 'arrowheadStart-style.dot' | 'arrowheadStart-style.inverted' | 'arrowheadStart-style.none' | 'arrowheadStart-style.pipe' | 'arrowheadStart-style.square' | 'arrowheadStart-style.triangle' | 'assets.files.amount-too-many' | 'assets.files.maximum-size' | 'assets.files.size-too-big' | 'assets.files.type-not-allowed' | 'assets.files.upload-failed' | 'assets.url.failed' | 'color-style.black' | 'color-style.blue' | 'color-style.green' | 'color-style.grey' | 'color-style.light-blue' | 'color-style.light-green' | 'color-style.light-red' | 'color-style.light-violet' | 'color-style.orange' | 'color-style.red' | 'color-style.violet' | 'color-style.white' | 'color-style.yellow' | 'context-menu.arrange' | 'context-menu.copy-as' | 'context-menu.edit' | 'context-menu.export-all-as' | 'context-menu.export-as' | 'context-menu.move-to-page' | 'context-menu.reorder' | 'context-menu.title' | 'context.pages.new-page' | 'cursor-chat.type-to-chat' | 'dash-style.dashed' | 'dash-style.dotted' | 'dash-style.draw' | 'dash-style.solid' | 'document-name-menu.copy-link' | 'document.default-name' | 'edit-link-dialog.cancel' | 'edit-link-dialog.clear' | 'edit-link-dialog.detail' | 'edit-link-dialog.external-link' | 'edit-link-dialog.invalid-url' | 'edit-link-dialog.save' | 'edit-link-dialog.title' | 'edit-link-dialog.url' | 'embed-dialog.back' | 'embed-dialog.cancel' | 'embed-dialog.create' | 'embed-dialog.instruction' | 'embed-dialog.invalid-url' | 'embed-dialog.title' | 'embed-dialog.url' | 'file-system.confirm-clear.cancel' | 'file-system.confirm-clear.continue' | 'file-system.confirm-clear.description' | 'file-system.confirm-clear.dont-show-again' | 'file-system.confirm-clear.title' | 'file-system.confirm-open.cancel' | 'file-system.confirm-open.description' | 'file-system.confirm-open.dont-show-again' | 'file-system.confirm-open.open' | 'file-system.confirm-open.title' | 'file-system.file-open-error.file-format-version-too-new' | 'file-system.file-open-error.generic-corrupted-file' | 'file-system.file-open-error.not-a-tldraw-file' | 'file-system.file-open-error.title' | 'file-system.shared-document-file-open-error.description' | 'file-system.shared-document-file-open-error.title' | 'fill-style.fill' | 'fill-style.none' | 'fill-style.pattern' | 'fill-style.semi' | 'fill-style.solid' | 'focus-mode.toggle-focus-mode' | 'font-style.draw' | 'font-style.mono' | 'font-style.sans' | 'font-style.serif' | 'geo-style.arrow-down' | 'geo-style.arrow-left' | 'geo-style.arrow-right' | 'geo-style.arrow-up' | 'geo-style.check-box' | 'geo-style.cloud' | 'geo-style.diamond' | 'geo-style.ellipse' | 'geo-style.heart' | 'geo-style.hexagon' | 'geo-style.octagon' | 'geo-style.oval' | 'geo-style.pentagon' | 'geo-style.rectangle' | 'geo-style.rhombus-2' | 'geo-style.rhombus' | 'geo-style.star' | 'geo-style.trapezoid' | 'geo-style.triangle' | 'geo-style.x-box' | 'handle.crop.bottom-left' | 'handle.crop.bottom-right' | 'handle.crop.bottom' | 'handle.crop.left' | 'handle.crop.right' | 'handle.crop.top-left' | 'handle.crop.top-right' | 'handle.crop.top' | 'handle.resize-bottom-left' | 'handle.resize-bottom-right' | 'handle.resize-bottom' | 'handle.resize-left' | 'handle.resize-right' | 'handle.resize-top-left' | 'handle.resize-top-right' | 'handle.resize-top' | 'handle.rotate.bottom_left_rotate' | 'handle.rotate.bottom_right_rotate' | 'handle.rotate.mobile_rotate' | 'handle.rotate.top_left_rotate' | 'handle.rotate.top_right_rotate' | 'help-menu.about' | 'help-menu.discord' | 'help-menu.github' | 'help-menu.import-tldr-file' | 'help-menu.keyboard-shortcuts' | 'help-menu.privacy' | 'help-menu.terms' | 'help-menu.title' | 'help-menu.twitter' | 'menu.accessibility' | 'menu.copy-as' | 'menu.edit' | 'menu.export-as' | 'menu.file' | 'menu.language' | 'menu.preferences' | 'menu.theme' | 'menu.title' | 'menu.view' | 'navigation-zone.minimap' | 'navigation-zone.title' | 'navigation-zone.toggle-minimap' | 'navigation-zone.zoom' | 'opacity-style.0.1' | 'opacity-style.0.25' | 'opacity-style.0.5' | 'opacity-style.0.75' | 'opacity-style.1' | 'page-menu.create-new-page' | 'page-menu.edit-done' | 'page-menu.edit-start' | 'page-menu.go-to-page' | 'page-menu.max-page-count-reached' | 'page-menu.new-page-initial-name' | 'page-menu.submenu.delete' | 'page-menu.submenu.duplicate-page' | 'page-menu.submenu.move-down' | 'page-menu.submenu.move-up' | 'page-menu.submenu.rename' | 'page-menu.submenu.title' | 'page-menu.title' | 'people-menu.anonymous-user' | 'people-menu.avatar-color' | 'people-menu.change-color' | 'people-menu.change-name' | 'people-menu.follow' | 'people-menu.following' | 'people-menu.invite' | 'people-menu.leading' | 'people-menu.title' | 'people-menu.user' | 'share-menu.copied' | 'share-menu.copy-link-note' | 'share-menu.copy-link' | 'share-menu.copy-readonly-link-note' | 'share-menu.copy-readonly-link' | 'share-menu.create-snapshot-link' | 'share-menu.creating-project' | 'share-menu.fork-note' | 'share-menu.offline-note' | 'share-menu.project-too-large' | 'share-menu.save-note' | 'share-menu.share-project' | 'share-menu.snapshot-link-note' | 'share-menu.title' | 'share-menu.upload-failed' | 'sharing.confirm-leave.cancel' | 'sharing.confirm-leave.description' | 'sharing.confirm-leave.dont-show-again' | 'sharing.confirm-leave.leave' | 'sharing.confirm-leave.title' | 'shortcuts-dialog.a11y' | 'shortcuts-dialog.collaboration' | 'shortcuts-dialog.edit' | 'shortcuts-dialog.file' | 'shortcuts-dialog.preferences' | 'shortcuts-dialog.text-formatting' | 'shortcuts-dialog.title' | 'shortcuts-dialog.tools' | 'shortcuts-dialog.transform' | 'shortcuts-dialog.view' | 'size-style.l' | 'size-style.m' | 'size-style.s' | 'size-style.xl' | 'spline-style.cubic' | 'spline-style.line' | 'status.offline' | 'style-panel.align' | 'style-panel.arrow-kind' | 'style-panel.arrowhead-end' | 'style-panel.arrowhead-start' | 'style-panel.arrowheads' | 'style-panel.color' | 'style-panel.dash' | 'style-panel.fill' | 'style-panel.font' | 'style-panel.geo' | 'style-panel.label-align' | 'style-panel.mixed' | 'style-panel.opacity' | 'style-panel.position' | 'style-panel.selected' | 'style-panel.size' | 'style-panel.spline' | 'style-panel.title' | 'style-panel.vertical-align' | 'theme.dark' | 'theme.light' | 'theme.system' | 'toast.close' | 'toast.error.copy-fail.desc' | 'toast.error.copy-fail.title' | 'toast.error.export-fail.desc' | 'toast.error.export-fail.title' | 'toast.error' | 'toast.info' | 'toast.success' | 'toast.warning' | 'tool-panel.more' | 'tool-panel.title' | 'tool.arrow-down' | 'tool.arrow-left' | 'tool.arrow-right' | 'tool.arrow-up' | 'tool.arrow' | 'tool.aspect-ratio.circle' | 'tool.aspect-ratio.landscape' | 'tool.aspect-ratio.original' | 'tool.aspect-ratio.portrait' | 'tool.aspect-ratio.square' | 'tool.aspect-ratio.wide' | 'tool.aspect-ratio' | 'tool.bookmark' | 'tool.check-box' | 'tool.cloud' | 'tool.diamond' | 'tool.draw' | 'tool.ellipse' | 'tool.embed' | 'tool.eraser' | 'tool.flip-horz' | 'tool.flip-vert' | 'tool.frame' | 'tool.hand' | 'tool.heart' | 'tool.hexagon' | 'tool.highlight' | 'tool.image-crop-confirm' | 'tool.image-crop' | 'tool.image-toolbar-title' | 'tool.image-zoom' | 'tool.laser' | 'tool.line' | 'tool.media-alt-text-confirm' | 'tool.media-alt-text-desc' | 'tool.media-alt-text' | 'tool.media' | 'tool.note' | 'tool.octagon' | 'tool.oval' | 'tool.pentagon' | 'tool.pointer-down' | 'tool.rectangle' | 'tool.replace-media' | 'tool.rhombus' | 'tool.rich-text-bold' | 'tool.rich-text-bulletList' | 'tool.rich-text-code' | 'tool.rich-text-header' | 'tool.rich-text-highlight' | 'tool.rich-text-italic' | 'tool.rich-text-link-remove' | 'tool.rich-text-link-visit' | 'tool.rich-text-link' | 'tool.rich-text-orderedList' | 'tool.rich-text-strikethrough' | 'tool.rich-text-toolbar-title' | 'tool.rotate-cw' | 'tool.select' | 'tool.star' | 'tool.text' | 'tool.trapezoid' | 'tool.triangle' | 'tool.x-box' | 'ui.checked' | 'ui.close' | 'ui.unchecked' | 'verticalAlign-style.end' | 'verticalAlign-style.middle' | 'verticalAlign-style.start' | 'vscode.file-open.backup-failed' | 'vscode.file-open.backup-saved' | 'vscode.file-open.backup' | 'vscode.file-open.desc' | 'vscode.file-open.dont-show-again' | 'vscode.file-open.open';
4227
4229
 
4228
4230
  /** @public */
4229
4231
  export declare interface TLUiTranslationProviderProps {
@@ -4485,7 +4487,9 @@ export declare function useEditablePlainText(shapeId: TLShapeId, type: string, t
4485
4487
  handleChange: ({ plaintext }: {
4486
4488
  plaintext: string;
4487
4489
  }) => void;
4488
- handleDoubleClick: (e: React_3.MouseEvent) => void;
4490
+ handleDoubleClick: (e: {
4491
+ nativeEvent: Event;
4492
+ } | Event) => void;
4489
4493
  handleFocus: () => void;
4490
4494
  handleInputPointerDown: (e: React_3.PointerEvent) => void;
4491
4495
  handleKeyDown: (e: KeyboardEvent) => void;
@@ -4502,7 +4506,9 @@ export declare function useEditableRichText(shapeId: TLShapeId, type: string, ri
4502
4506
  handleChange: ({ richText }: {
4503
4507
  richText: TLRichText;
4504
4508
  }) => void;
4505
- handleDoubleClick: (e: React.MouseEvent) => void;
4509
+ handleDoubleClick: (e: {
4510
+ nativeEvent: Event;
4511
+ } | Event) => void;
4506
4512
  handleFocus: () => void;
4507
4513
  handleInputPointerDown: (e: React.PointerEvent) => void;
4508
4514
  handleKeyDown: (e: KeyboardEvent) => void;
@@ -524,7 +524,7 @@ import {
524
524
  } from "./lib/utils/tldr/file.mjs";
525
525
  registerTldrawLibraryVersion(
526
526
  "tldraw",
527
- "3.16.0-canary.e4220f725a90",
527
+ "3.16.0-canary.e455ab838b8f",
528
528
  "esm"
529
529
  );
530
530
  export {
@@ -9,7 +9,6 @@ import {
9
9
  debounce,
10
10
  getHashForString,
11
11
  lerp,
12
- markEventAsHandled,
13
12
  tlenv,
14
13
  toDomPrecision,
15
14
  useEditor,
@@ -98,7 +97,7 @@ function BookmarkShapeComponent({ shape }) {
98
97
  const onFaviconError = () => setIsFaviconValid(false);
99
98
  const markAsHandledOnShiftKey = useCallback(
100
99
  (e) => {
101
- if (!editor.inputs.shiftKey) markEventAsHandled(e);
100
+ if (!editor.inputs.shiftKey) editor.markEventAsHandled(e);
102
101
  },
103
102
  [editor]
104
103
  );
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/bookmark/BookmarkShapeUtil.tsx"],
4
- "sourcesContent": ["import {\n\tAssetRecordType,\n\tBaseBoxShapeUtil,\n\tEditor,\n\tHTMLContainer,\n\tT,\n\tTLAssetId,\n\tTLBookmarkAsset,\n\tTLBookmarkShape,\n\tTLBookmarkShapeProps,\n\tbookmarkShapeMigrations,\n\tbookmarkShapeProps,\n\tdebounce,\n\tgetHashForString,\n\tlerp,\n\tmarkEventAsHandled,\n\ttlenv,\n\ttoDomPrecision,\n\tuseEditor,\n\tuseSvgExportContext,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { PointerEventHandler, useCallback, useState } from 'react'\nimport { convertCommonTitleHTMLEntities } from '../../utils/text/text'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { LINK_ICON } from '../shared/icons-editor'\nimport { getRotatedBoxShadow } from '../shared/rotated-box-shadow'\n\nconst BOOKMARK_WIDTH = 300\nconst BOOKMARK_HEIGHT = 320\nconst BOOKMARK_JUST_URL_HEIGHT = 46\nconst SHORT_BOOKMARK_HEIGHT = 101\n\n/** @public */\nexport class BookmarkShapeUtil extends BaseBoxShapeUtil<TLBookmarkShape> {\n\tstatic override type = 'bookmark' as const\n\tstatic override props = bookmarkShapeProps\n\tstatic override migrations = bookmarkShapeMigrations\n\n\toverride canResize() {\n\t\treturn false\n\t}\n\n\toverride hideSelectionBoundsFg() {\n\t\treturn true\n\t}\n\n\toverride getText(shape: TLBookmarkShape) {\n\t\treturn shape.props.url\n\t}\n\n\toverride getAriaDescriptor(shape: TLBookmarkShape) {\n\t\tconst asset = (\n\t\t\tshape.props.assetId ? this.editor.getAsset(shape.props.assetId) : null\n\t\t) as TLBookmarkAsset | null\n\n\t\tif (!asset?.props.title) return undefined\n\n\t\treturn (\n\t\t\tconvertCommonTitleHTMLEntities(asset.props.title) +\n\t\t\t(asset.props.description ? ', ' + asset.props.description : '')\n\t\t)\n\t}\n\n\toverride getDefaultProps(): TLBookmarkShape['props'] {\n\t\treturn {\n\t\t\turl: '',\n\t\t\tw: BOOKMARK_WIDTH,\n\t\t\th: BOOKMARK_HEIGHT,\n\t\t\tassetId: null,\n\t\t}\n\t}\n\n\toverride component(shape: TLBookmarkShape) {\n\t\treturn <BookmarkShapeComponent shape={shape} />\n\t}\n\n\toverride indicator(shape: TLBookmarkShape) {\n\t\treturn (\n\t\t\t<rect\n\t\t\t\twidth={toDomPrecision(shape.props.w)}\n\t\t\t\theight={toDomPrecision(shape.props.h)}\n\t\t\t\trx=\"6\"\n\t\t\t\try=\"6\"\n\t\t\t/>\n\t\t)\n\t}\n\n\toverride onBeforeCreate(next: TLBookmarkShape) {\n\t\treturn getBookmarkSize(this.editor, next)\n\t}\n\n\toverride onBeforeUpdate(prev: TLBookmarkShape, shape: TLBookmarkShape) {\n\t\tif (prev.props.url !== shape.props.url) {\n\t\t\tif (!T.linkUrl.isValid(shape.props.url)) {\n\t\t\t\treturn { ...shape, props: { ...shape.props, url: prev.props.url } }\n\t\t\t} else {\n\t\t\t\tupdateBookmarkAssetOnUrlChange(this.editor, shape)\n\t\t\t}\n\t\t}\n\n\t\tif (prev.props.assetId !== shape.props.assetId) {\n\t\t\treturn getBookmarkSize(this.editor, shape)\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLBookmarkShape,\n\t\tendShape: TLBookmarkShape,\n\t\tt: number\n\t): TLBookmarkShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n}\n\nfunction BookmarkShapeComponent({ shape }: { shape: TLBookmarkShape }) {\n\tconst editor = useEditor()\n\n\tconst asset = (\n\t\tshape.props.assetId ? editor.getAsset(shape.props.assetId) : null\n\t) as TLBookmarkAsset\n\n\tconst isSafariExport = !!useSvgExportContext() && tlenv.isSafari\n\n\tconst pageRotation = editor.getShapePageTransform(shape)!.rotation()\n\n\tconst address = getHumanReadableAddress(shape)\n\n\tconst [isFaviconValid, setIsFaviconValid] = useState(true)\n\tconst onFaviconError = () => setIsFaviconValid(false)\n\n\tconst markAsHandledOnShiftKey = useCallback<PointerEventHandler>(\n\t\t(e) => {\n\t\t\tif (!editor.inputs.shiftKey) markEventAsHandled(e)\n\t\t},\n\t\t[editor]\n\t)\n\n\treturn (\n\t\t<HTMLContainer>\n\t\t\t<div\n\t\t\t\tclassName={classNames(\n\t\t\t\t\t'tl-bookmark__container',\n\t\t\t\t\tisSafariExport && 'tl-bookmark__container--safariExport'\n\t\t\t\t)}\n\t\t\t\tstyle={{\n\t\t\t\t\tboxShadow: isSafariExport ? undefined : getRotatedBoxShadow(pageRotation),\n\t\t\t\t\tmaxHeight: shape.props.h,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{(!asset || asset.props.image) && (\n\t\t\t\t\t<div className=\"tl-bookmark__image_container\">\n\t\t\t\t\t\t{asset ? (\n\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\tclassName=\"tl-bookmark__image\"\n\t\t\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\t\t\tsrc={asset?.props.image}\n\t\t\t\t\t\t\t\talt={asset?.props.title || ''}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<div className=\"tl-bookmark__placeholder\" />\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{asset?.props.image && <HyperlinkButton url={shape.props.url} />}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t<div className=\"tl-bookmark__copy_container\">\n\t\t\t\t\t{asset?.props.title ? (\n\t\t\t\t\t\t<h2 className=\"tl-bookmark__heading\">\n\t\t\t\t\t\t\t{convertCommonTitleHTMLEntities(asset.props.title)}\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{asset?.props.description && asset?.props.image ? (\n\t\t\t\t\t\t<p className=\"tl-bookmark__description\">{asset.props.description}</p>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<a\n\t\t\t\t\t\tclassName=\"tl-bookmark__link\"\n\t\t\t\t\t\thref={shape.props.url || ''}\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\tonPointerDown={markAsHandledOnShiftKey}\n\t\t\t\t\t\tonPointerUp={markAsHandledOnShiftKey}\n\t\t\t\t\t>\n\t\t\t\t\t\t{isFaviconValid && asset?.props.favicon ? (\n\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\tclassName=\"tl-bookmark__favicon\"\n\t\t\t\t\t\t\t\tsrc={asset?.props.favicon}\n\t\t\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\t\t\tonError={onFaviconError}\n\t\t\t\t\t\t\t\talt={`favicon of ${address}`}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"tl-hyperlink__icon\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tmask: `url(\"${LINK_ICON}\") center 100% / 100% no-repeat`,\n\t\t\t\t\t\t\t\t\tWebkitMask: `url(\"${LINK_ICON}\") center 100% / 100% no-repeat`,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<span>{address}</span>\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</HTMLContainer>\n\t)\n}\n\nfunction getBookmarkSize(editor: Editor, shape: TLBookmarkShape) {\n\tconst asset = (\n\t\tshape.props.assetId ? editor.getAsset(shape.props.assetId) : null\n\t) as TLBookmarkAsset\n\n\tlet h = BOOKMARK_HEIGHT\n\n\tif (asset) {\n\t\tif (!asset.props.image) {\n\t\t\tif (!asset.props.title) {\n\t\t\t\th = BOOKMARK_JUST_URL_HEIGHT\n\t\t\t} else {\n\t\t\t\th = SHORT_BOOKMARK_HEIGHT\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\t...shape,\n\t\tprops: {\n\t\t\t...shape.props,\n\t\t\th,\n\t\t},\n\t}\n}\n\n/** @internal */\nexport const getHumanReadableAddress = (shape: TLBookmarkShape) => {\n\ttry {\n\t\tconst url = new URL(shape.props.url)\n\t\t// we want the hostname without any www\n\t\treturn url.hostname.replace(/^www\\./, '')\n\t} catch {\n\t\treturn shape.props.url\n\t}\n}\n\nfunction updateBookmarkAssetOnUrlChange(editor: Editor, shape: TLBookmarkShape) {\n\tconst { url } = shape.props\n\n\t// Derive the asset id from the URL\n\tconst assetId: TLAssetId = AssetRecordType.createId(getHashForString(url))\n\n\tif (editor.getAsset(assetId)) {\n\t\t// Existing asset for this URL?\n\t\tif (shape.props.assetId !== assetId) {\n\t\t\teditor.updateShapes<TLBookmarkShape>([\n\t\t\t\t{\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tprops: { assetId },\n\t\t\t\t},\n\t\t\t])\n\t\t}\n\t} else {\n\t\t// No asset for this URL?\n\n\t\t// First, clear out the existing asset reference\n\t\teditor.updateShapes<TLBookmarkShape>([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: { assetId: null },\n\t\t\t},\n\t\t])\n\n\t\t// Then try to asyncronously create a new one\n\t\tcreateBookmarkAssetOnUrlChange(editor, shape)\n\t}\n}\n\nconst createBookmarkAssetOnUrlChange = debounce(async (editor: Editor, shape: TLBookmarkShape) => {\n\tif (editor.isDisposed) return\n\n\tconst { url } = shape.props\n\n\t// Create the asset using the external content manager's createAssetFromUrl method.\n\t// This may be overwritten by the user (for example, we overwrite it on tldraw.com)\n\tconst asset = await editor.getAssetForExternalContent({ type: 'url', url })\n\n\tif (!asset) {\n\t\t// No asset? Just leave the bookmark as a null assetId.\n\t\treturn\n\t}\n\n\teditor.run(() => {\n\t\t// Create the new asset\n\t\teditor.createAssets([asset])\n\n\t\t// And update the shape\n\t\teditor.updateShapes<TLBookmarkShape>([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: { assetId: asset.id },\n\t\t\t},\n\t\t])\n\t})\n}, 500)\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tAssetRecordType,\n\tBaseBoxShapeUtil,\n\tEditor,\n\tHTMLContainer,\n\tT,\n\tTLAssetId,\n\tTLBookmarkAsset,\n\tTLBookmarkShape,\n\tTLBookmarkShapeProps,\n\tbookmarkShapeMigrations,\n\tbookmarkShapeProps,\n\tdebounce,\n\tgetHashForString,\n\tlerp,\n\ttlenv,\n\ttoDomPrecision,\n\tuseEditor,\n\tuseSvgExportContext,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { PointerEventHandler, useCallback, useState } from 'react'\nimport { convertCommonTitleHTMLEntities } from '../../utils/text/text'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { LINK_ICON } from '../shared/icons-editor'\nimport { getRotatedBoxShadow } from '../shared/rotated-box-shadow'\n\nconst BOOKMARK_WIDTH = 300\nconst BOOKMARK_HEIGHT = 320\nconst BOOKMARK_JUST_URL_HEIGHT = 46\nconst SHORT_BOOKMARK_HEIGHT = 101\n\n/** @public */\nexport class BookmarkShapeUtil extends BaseBoxShapeUtil<TLBookmarkShape> {\n\tstatic override type = 'bookmark' as const\n\tstatic override props = bookmarkShapeProps\n\tstatic override migrations = bookmarkShapeMigrations\n\n\toverride canResize() {\n\t\treturn false\n\t}\n\n\toverride hideSelectionBoundsFg() {\n\t\treturn true\n\t}\n\n\toverride getText(shape: TLBookmarkShape) {\n\t\treturn shape.props.url\n\t}\n\n\toverride getAriaDescriptor(shape: TLBookmarkShape) {\n\t\tconst asset = (\n\t\t\tshape.props.assetId ? this.editor.getAsset(shape.props.assetId) : null\n\t\t) as TLBookmarkAsset | null\n\n\t\tif (!asset?.props.title) return undefined\n\n\t\treturn (\n\t\t\tconvertCommonTitleHTMLEntities(asset.props.title) +\n\t\t\t(asset.props.description ? ', ' + asset.props.description : '')\n\t\t)\n\t}\n\n\toverride getDefaultProps(): TLBookmarkShape['props'] {\n\t\treturn {\n\t\t\turl: '',\n\t\t\tw: BOOKMARK_WIDTH,\n\t\t\th: BOOKMARK_HEIGHT,\n\t\t\tassetId: null,\n\t\t}\n\t}\n\n\toverride component(shape: TLBookmarkShape) {\n\t\treturn <BookmarkShapeComponent shape={shape} />\n\t}\n\n\toverride indicator(shape: TLBookmarkShape) {\n\t\treturn (\n\t\t\t<rect\n\t\t\t\twidth={toDomPrecision(shape.props.w)}\n\t\t\t\theight={toDomPrecision(shape.props.h)}\n\t\t\t\trx=\"6\"\n\t\t\t\try=\"6\"\n\t\t\t/>\n\t\t)\n\t}\n\n\toverride onBeforeCreate(next: TLBookmarkShape) {\n\t\treturn getBookmarkSize(this.editor, next)\n\t}\n\n\toverride onBeforeUpdate(prev: TLBookmarkShape, shape: TLBookmarkShape) {\n\t\tif (prev.props.url !== shape.props.url) {\n\t\t\tif (!T.linkUrl.isValid(shape.props.url)) {\n\t\t\t\treturn { ...shape, props: { ...shape.props, url: prev.props.url } }\n\t\t\t} else {\n\t\t\t\tupdateBookmarkAssetOnUrlChange(this.editor, shape)\n\t\t\t}\n\t\t}\n\n\t\tif (prev.props.assetId !== shape.props.assetId) {\n\t\t\treturn getBookmarkSize(this.editor, shape)\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLBookmarkShape,\n\t\tendShape: TLBookmarkShape,\n\t\tt: number\n\t): TLBookmarkShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n}\n\nfunction BookmarkShapeComponent({ shape }: { shape: TLBookmarkShape }) {\n\tconst editor = useEditor()\n\n\tconst asset = (\n\t\tshape.props.assetId ? editor.getAsset(shape.props.assetId) : null\n\t) as TLBookmarkAsset\n\n\tconst isSafariExport = !!useSvgExportContext() && tlenv.isSafari\n\n\tconst pageRotation = editor.getShapePageTransform(shape)!.rotation()\n\n\tconst address = getHumanReadableAddress(shape)\n\n\tconst [isFaviconValid, setIsFaviconValid] = useState(true)\n\tconst onFaviconError = () => setIsFaviconValid(false)\n\n\tconst markAsHandledOnShiftKey = useCallback<PointerEventHandler>(\n\t\t(e) => {\n\t\t\tif (!editor.inputs.shiftKey) editor.markEventAsHandled(e)\n\t\t},\n\t\t[editor]\n\t)\n\n\treturn (\n\t\t<HTMLContainer>\n\t\t\t<div\n\t\t\t\tclassName={classNames(\n\t\t\t\t\t'tl-bookmark__container',\n\t\t\t\t\tisSafariExport && 'tl-bookmark__container--safariExport'\n\t\t\t\t)}\n\t\t\t\tstyle={{\n\t\t\t\t\tboxShadow: isSafariExport ? undefined : getRotatedBoxShadow(pageRotation),\n\t\t\t\t\tmaxHeight: shape.props.h,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{(!asset || asset.props.image) && (\n\t\t\t\t\t<div className=\"tl-bookmark__image_container\">\n\t\t\t\t\t\t{asset ? (\n\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\tclassName=\"tl-bookmark__image\"\n\t\t\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\t\t\tsrc={asset?.props.image}\n\t\t\t\t\t\t\t\talt={asset?.props.title || ''}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<div className=\"tl-bookmark__placeholder\" />\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{asset?.props.image && <HyperlinkButton url={shape.props.url} />}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t<div className=\"tl-bookmark__copy_container\">\n\t\t\t\t\t{asset?.props.title ? (\n\t\t\t\t\t\t<h2 className=\"tl-bookmark__heading\">\n\t\t\t\t\t\t\t{convertCommonTitleHTMLEntities(asset.props.title)}\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{asset?.props.description && asset?.props.image ? (\n\t\t\t\t\t\t<p className=\"tl-bookmark__description\">{asset.props.description}</p>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<a\n\t\t\t\t\t\tclassName=\"tl-bookmark__link\"\n\t\t\t\t\t\thref={shape.props.url || ''}\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\tonPointerDown={markAsHandledOnShiftKey}\n\t\t\t\t\t\tonPointerUp={markAsHandledOnShiftKey}\n\t\t\t\t\t>\n\t\t\t\t\t\t{isFaviconValid && asset?.props.favicon ? (\n\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\tclassName=\"tl-bookmark__favicon\"\n\t\t\t\t\t\t\t\tsrc={asset?.props.favicon}\n\t\t\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\t\t\tonError={onFaviconError}\n\t\t\t\t\t\t\t\talt={`favicon of ${address}`}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"tl-hyperlink__icon\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tmask: `url(\"${LINK_ICON}\") center 100% / 100% no-repeat`,\n\t\t\t\t\t\t\t\t\tWebkitMask: `url(\"${LINK_ICON}\") center 100% / 100% no-repeat`,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<span>{address}</span>\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</HTMLContainer>\n\t)\n}\n\nfunction getBookmarkSize(editor: Editor, shape: TLBookmarkShape) {\n\tconst asset = (\n\t\tshape.props.assetId ? editor.getAsset(shape.props.assetId) : null\n\t) as TLBookmarkAsset\n\n\tlet h = BOOKMARK_HEIGHT\n\n\tif (asset) {\n\t\tif (!asset.props.image) {\n\t\t\tif (!asset.props.title) {\n\t\t\t\th = BOOKMARK_JUST_URL_HEIGHT\n\t\t\t} else {\n\t\t\t\th = SHORT_BOOKMARK_HEIGHT\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\t...shape,\n\t\tprops: {\n\t\t\t...shape.props,\n\t\t\th,\n\t\t},\n\t}\n}\n\n/** @internal */\nexport const getHumanReadableAddress = (shape: TLBookmarkShape) => {\n\ttry {\n\t\tconst url = new URL(shape.props.url)\n\t\t// we want the hostname without any www\n\t\treturn url.hostname.replace(/^www\\./, '')\n\t} catch {\n\t\treturn shape.props.url\n\t}\n}\n\nfunction updateBookmarkAssetOnUrlChange(editor: Editor, shape: TLBookmarkShape) {\n\tconst { url } = shape.props\n\n\t// Derive the asset id from the URL\n\tconst assetId: TLAssetId = AssetRecordType.createId(getHashForString(url))\n\n\tif (editor.getAsset(assetId)) {\n\t\t// Existing asset for this URL?\n\t\tif (shape.props.assetId !== assetId) {\n\t\t\teditor.updateShapes<TLBookmarkShape>([\n\t\t\t\t{\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tprops: { assetId },\n\t\t\t\t},\n\t\t\t])\n\t\t}\n\t} else {\n\t\t// No asset for this URL?\n\n\t\t// First, clear out the existing asset reference\n\t\teditor.updateShapes<TLBookmarkShape>([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: { assetId: null },\n\t\t\t},\n\t\t])\n\n\t\t// Then try to asyncronously create a new one\n\t\tcreateBookmarkAssetOnUrlChange(editor, shape)\n\t}\n}\n\nconst createBookmarkAssetOnUrlChange = debounce(async (editor: Editor, shape: TLBookmarkShape) => {\n\tif (editor.isDisposed) return\n\n\tconst { url } = shape.props\n\n\t// Create the asset using the external content manager's createAssetFromUrl method.\n\t// This may be overwritten by the user (for example, we overwrite it on tldraw.com)\n\tconst asset = await editor.getAssetForExternalContent({ type: 'url', url })\n\n\tif (!asset) {\n\t\t// No asset? Just leave the bookmark as a null assetId.\n\t\treturn\n\t}\n\n\teditor.run(() => {\n\t\t// Create the new asset\n\t\teditor.createAssets([asset])\n\n\t\t// And update the shape\n\t\teditor.updateShapes<TLBookmarkShape>([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: { assetId: asset.id },\n\t\t\t},\n\t\t])\n\t})\n}, 500)\n"],
5
+ "mappings": "AAyES,cAgFJ,YAhFI;AAzET;AAAA,EACC;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EAKA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,OAAO,gBAAgB;AACvB,SAA8B,aAAa,gBAAgB;AAC3D,SAAS,sCAAsC;AAC/C,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;AAC1B,SAAS,2BAA2B;AAEpC,MAAM,iBAAiB;AACvB,MAAM,kBAAkB;AACxB,MAAM,2BAA2B;AACjC,MAAM,wBAAwB;AAGvB,MAAM,0BAA0B,iBAAkC;AAAA,EACxE,OAAgB,OAAO;AAAA,EACvB,OAAgB,QAAQ;AAAA,EACxB,OAAgB,aAAa;AAAA,EAEpB,YAAY;AACpB,WAAO;AAAA,EACR;AAAA,EAES,wBAAwB;AAChC,WAAO;AAAA,EACR;AAAA,EAES,QAAQ,OAAwB;AACxC,WAAO,MAAM,MAAM;AAAA,EACpB;AAAA,EAES,kBAAkB,OAAwB;AAClD,UAAM,QACL,MAAM,MAAM,UAAU,KAAK,OAAO,SAAS,MAAM,MAAM,OAAO,IAAI;AAGnE,QAAI,CAAC,OAAO,MAAM,MAAO,QAAO;AAEhC,WACC,+BAA+B,MAAM,MAAM,KAAK,KAC/C,MAAM,MAAM,cAAc,OAAO,MAAM,MAAM,cAAc;AAAA,EAE9D;AAAA,EAES,kBAA4C;AACpD,WAAO;AAAA,MACN,KAAK;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,MACH,SAAS;AAAA,IACV;AAAA,EACD;AAAA,EAES,UAAU,OAAwB;AAC1C,WAAO,oBAAC,0BAAuB,OAAc;AAAA,EAC9C;AAAA,EAES,UAAU,OAAwB;AAC1C,WACC;AAAA,MAAC;AAAA;AAAA,QACA,OAAO,eAAe,MAAM,MAAM,CAAC;AAAA,QACnC,QAAQ,eAAe,MAAM,MAAM,CAAC;AAAA,QACpC,IAAG;AAAA,QACH,IAAG;AAAA;AAAA,IACJ;AAAA,EAEF;AAAA,EAES,eAAe,MAAuB;AAC9C,WAAO,gBAAgB,KAAK,QAAQ,IAAI;AAAA,EACzC;AAAA,EAES,eAAe,MAAuB,OAAwB;AACtE,QAAI,KAAK,MAAM,QAAQ,MAAM,MAAM,KAAK;AACvC,UAAI,CAAC,EAAE,QAAQ,QAAQ,MAAM,MAAM,GAAG,GAAG;AACxC,eAAO,EAAE,GAAG,OAAO,OAAO,EAAE,GAAG,MAAM,OAAO,KAAK,KAAK,MAAM,IAAI,EAAE;AAAA,MACnE,OAAO;AACN,uCAA+B,KAAK,QAAQ,KAAK;AAAA,MAClD;AAAA,IACD;AAEA,QAAI,KAAK,MAAM,YAAY,MAAM,MAAM,SAAS;AAC/C,aAAO,gBAAgB,KAAK,QAAQ,KAAK;AAAA,IAC1C;AAAA,EACD;AAAA,EACS,qBACR,YACA,UACA,GACuB;AACvB,WAAO;AAAA,MACN,GAAI,IAAI,MAAM,SAAS,QAAQ,WAAW;AAAA,MAC1C,GAAG,KAAK,WAAW,MAAM,GAAG,SAAS,MAAM,GAAG,CAAC;AAAA,MAC/C,GAAG,KAAK,WAAW,MAAM,GAAG,SAAS,MAAM,GAAG,CAAC;AAAA,IAChD;AAAA,EACD;AACD;AAEA,SAAS,uBAAuB,EAAE,MAAM,GAA+B;AACtE,QAAM,SAAS,UAAU;AAEzB,QAAM,QACL,MAAM,MAAM,UAAU,OAAO,SAAS,MAAM,MAAM,OAAO,IAAI;AAG9D,QAAM,iBAAiB,CAAC,CAAC,oBAAoB,KAAK,MAAM;AAExD,QAAM,eAAe,OAAO,sBAAsB,KAAK,EAAG,SAAS;AAEnE,QAAM,UAAU,wBAAwB,KAAK;AAE7C,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,IAAI;AACzD,QAAM,iBAAiB,MAAM,kBAAkB,KAAK;AAEpD,QAAM,0BAA0B;AAAA,IAC/B,CAAC,MAAM;AACN,UAAI,CAAC,OAAO,OAAO,SAAU,QAAO,mBAAmB,CAAC;AAAA,IACzD;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AAEA,SACC,oBAAC,iBACA;AAAA,IAAC;AAAA;AAAA,MACA,WAAW;AAAA,QACV;AAAA,QACA,kBAAkB;AAAA,MACnB;AAAA,MACA,OAAO;AAAA,QACN,WAAW,iBAAiB,SAAY,oBAAoB,YAAY;AAAA,QACxE,WAAW,MAAM,MAAM;AAAA,MACxB;AAAA,MAEE;AAAA,UAAC,SAAS,MAAM,MAAM,UACvB,qBAAC,SAAI,WAAU,gCACb;AAAA,kBACA;AAAA,YAAC;AAAA;AAAA,cACA,WAAU;AAAA,cACV,WAAW;AAAA,cACX,gBAAe;AAAA,cACf,KAAK,OAAO,MAAM;AAAA,cAClB,KAAK,OAAO,MAAM,SAAS;AAAA;AAAA,UAC5B,IAEA,oBAAC,SAAI,WAAU,4BAA2B;AAAA,UAE1C,OAAO,MAAM,SAAS,oBAAC,mBAAgB,KAAK,MAAM,MAAM,KAAK;AAAA,WAC/D;AAAA,QAED,qBAAC,SAAI,WAAU,+BACb;AAAA,iBAAO,MAAM,QACb,oBAAC,QAAG,WAAU,wBACZ,yCAA+B,MAAM,MAAM,KAAK,GAClD,IACG;AAAA,UACH,OAAO,MAAM,eAAe,OAAO,MAAM,QACzC,oBAAC,OAAE,WAAU,4BAA4B,gBAAM,MAAM,aAAY,IAC9D;AAAA,UACJ;AAAA,YAAC;AAAA;AAAA,cACA,WAAU;AAAA,cACV,MAAM,MAAM,MAAM,OAAO;AAAA,cACzB,QAAO;AAAA,cACP,KAAI;AAAA,cACJ,WAAW;AAAA,cACX,eAAe;AAAA,cACf,aAAa;AAAA,cAEZ;AAAA,kCAAkB,OAAO,MAAM,UAC/B;AAAA,kBAAC;AAAA;AAAA,oBACA,WAAU;AAAA,oBACV,KAAK,OAAO,MAAM;AAAA,oBAClB,gBAAe;AAAA,oBACf,SAAS;AAAA,oBACT,KAAK,cAAc,OAAO;AAAA;AAAA,gBAC3B,IAEA;AAAA,kBAAC;AAAA;AAAA,oBACA,WAAU;AAAA,oBACV,OAAO;AAAA,sBACN,MAAM,QAAQ,SAAS;AAAA,sBACvB,YAAY,QAAQ,SAAS;AAAA,oBAC9B;AAAA;AAAA,gBACD;AAAA,gBAED,oBAAC,UAAM,mBAAQ;AAAA;AAAA;AAAA,UAChB;AAAA,WACD;AAAA;AAAA;AAAA,EACD,GACD;AAEF;AAEA,SAAS,gBAAgB,QAAgB,OAAwB;AAChE,QAAM,QACL,MAAM,MAAM,UAAU,OAAO,SAAS,MAAM,MAAM,OAAO,IAAI;AAG9D,MAAI,IAAI;AAER,MAAI,OAAO;AACV,QAAI,CAAC,MAAM,MAAM,OAAO;AACvB,UAAI,CAAC,MAAM,MAAM,OAAO;AACvB,YAAI;AAAA,MACL,OAAO;AACN,YAAI;AAAA,MACL;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AAAA,IACN,GAAG;AAAA,IACH,OAAO;AAAA,MACN,GAAG,MAAM;AAAA,MACT;AAAA,IACD;AAAA,EACD;AACD;AAGO,MAAM,0BAA0B,CAAC,UAA2B;AAClE,MAAI;AACH,UAAM,MAAM,IAAI,IAAI,MAAM,MAAM,GAAG;AAEnC,WAAO,IAAI,SAAS,QAAQ,UAAU,EAAE;AAAA,EACzC,QAAQ;AACP,WAAO,MAAM,MAAM;AAAA,EACpB;AACD;AAEA,SAAS,+BAA+B,QAAgB,OAAwB;AAC/E,QAAM,EAAE,IAAI,IAAI,MAAM;AAGtB,QAAM,UAAqB,gBAAgB,SAAS,iBAAiB,GAAG,CAAC;AAEzE,MAAI,OAAO,SAAS,OAAO,GAAG;AAE7B,QAAI,MAAM,MAAM,YAAY,SAAS;AACpC,aAAO,aAA8B;AAAA,QACpC;AAAA,UACC,IAAI,MAAM;AAAA,UACV,MAAM,MAAM;AAAA,UACZ,OAAO,EAAE,QAAQ;AAAA,QAClB;AAAA,MACD,CAAC;AAAA,IACF;AAAA,EACD,OAAO;AAIN,WAAO,aAA8B;AAAA,MACpC;AAAA,QACC,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,OAAO,EAAE,SAAS,KAAK;AAAA,MACxB;AAAA,IACD,CAAC;AAGD,mCAA+B,QAAQ,KAAK;AAAA,EAC7C;AACD;AAEA,MAAM,iCAAiC,SAAS,OAAO,QAAgB,UAA2B;AACjG,MAAI,OAAO,WAAY;AAEvB,QAAM,EAAE,IAAI,IAAI,MAAM;AAItB,QAAM,QAAQ,MAAM,OAAO,2BAA2B,EAAE,MAAM,OAAO,IAAI,CAAC;AAE1E,MAAI,CAAC,OAAO;AAEX;AAAA,EACD;AAEA,SAAO,IAAI,MAAM;AAEhB,WAAO,aAAa,CAAC,KAAK,CAAC;AAG3B,WAAO,aAA8B;AAAA,MACpC;AAAA,QACC,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,OAAO,EAAE,SAAS,MAAM,GAAG;AAAA,MAC5B;AAAA,IACD,CAAC;AAAA,EACF,CAAC;AACF,GAAG,GAAG;",
6
6
  "names": []
7
7
  }
@@ -1,13 +1,19 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { markEventAsHandled, useEditor } from "@tldraw/editor";
2
+ import { useEditor } from "@tldraw/editor";
3
3
  import { forwardRef, useCallback } from "react";
4
4
  import { defaultEmptyAs } from "../FrameShapeUtil.mjs";
5
5
  const FrameLabelInput = forwardRef(({ id, name, isEditing }, ref) => {
6
6
  const editor = useEditor();
7
+ const handlePointerDown = useCallback(
8
+ (e) => {
9
+ if (isEditing) editor.markEventAsHandled(e);
10
+ },
11
+ [editor, isEditing]
12
+ );
7
13
  const handleKeyDown = useCallback(
8
14
  (e) => {
9
15
  if (e.key === "Enter" && !e.nativeEvent.isComposing) {
10
- markEventAsHandled(e);
16
+ editor.markEventAsHandled(e);
11
17
  e.currentTarget.blur();
12
18
  editor.setEditingShape(null);
13
19
  }
@@ -62,7 +68,7 @@ const FrameLabelInput = forwardRef(({ id, name, isEditing }, ref) => {
62
68
  onKeyDown: handleKeyDown,
63
69
  onBlur: handleBlur,
64
70
  onChange: handleChange,
65
- onPointerDown: isEditing ? markEventAsHandled : void 0,
71
+ onPointerDown: handlePointerDown,
66
72
  draggable: false
67
73
  }
68
74
  ),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/shapes/frame/components/FrameLabelInput.tsx"],
4
- "sourcesContent": ["import { TLFrameShape, TLShapeId, markEventAsHandled, useEditor } from '@tldraw/editor'\nimport { forwardRef, useCallback } from 'react'\nimport { defaultEmptyAs } from '../FrameShapeUtil'\n\nexport const FrameLabelInput = forwardRef<\n\tHTMLInputElement,\n\t{ id: TLShapeId; name: string; isEditing: boolean }\n>(({ id, name, isEditing }, ref) => {\n\tconst editor = useEditor()\n\n\tconst handleKeyDown = useCallback(\n\t\t(e: React.KeyboardEvent<HTMLInputElement>) => {\n\t\t\tif (e.key === 'Enter' && !e.nativeEvent.isComposing) {\n\t\t\t\t// need to prevent the enter keydown making it's way up to the Idle state\n\t\t\t\t// and sending us back into edit mode\n\t\t\t\tmarkEventAsHandled(e)\n\t\t\t\te.currentTarget.blur()\n\t\t\t\teditor.setEditingShape(null)\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst handleBlur = useCallback(\n\t\t(e: React.FocusEvent<HTMLInputElement>) => {\n\t\t\tconst shape = editor.getShape<TLFrameShape>(id)\n\t\t\tif (!shape) return\n\n\t\t\tconst name = shape.props.name\n\t\t\tconst value = e.currentTarget.value.trim()\n\t\t\tif (name === value) return\n\n\t\t\teditor.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: 'frame',\n\t\t\t\t\tprops: { name: value },\n\t\t\t\t},\n\t\t\t])\n\t\t},\n\t\t[id, editor]\n\t)\n\n\tconst handleChange = useCallback(\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst shape = editor.getShape<TLFrameShape>(id)\n\t\t\tif (!shape) return\n\n\t\t\tconst name = shape.props.name\n\t\t\tconst value = e.currentTarget.value\n\t\t\tif (name === value) return\n\n\t\t\teditor.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: 'frame',\n\t\t\t\t\tprops: { name: value },\n\t\t\t\t},\n\t\t\t])\n\t\t},\n\t\t[id, editor]\n\t)\n\n\treturn (\n\t\t<div className={`tl-frame-label ${isEditing ? 'tl-frame-label__editing' : ''}`}>\n\t\t\t<input\n\t\t\t\tclassName=\"tl-frame-name-input\"\n\t\t\t\tref={ref}\n\t\t\t\tdisabled={!isEditing}\n\t\t\t\treadOnly={!isEditing}\n\t\t\t\tstyle={{ display: isEditing ? undefined : 'none' }}\n\t\t\t\tvalue={name}\n\t\t\t\tautoFocus\n\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\tonBlur={handleBlur}\n\t\t\t\tonChange={handleChange}\n\t\t\t\tonPointerDown={isEditing ? markEventAsHandled : undefined}\n\t\t\t\tdraggable={false}\n\t\t\t/>\n\t\t\t{defaultEmptyAs(name, 'Frame') + String.fromCharCode(8203)}\n\t\t</div>\n\t)\n})\n"],
5
- "mappings": "AAgEE,SACC,KADD;AAhEF,SAAkC,oBAAoB,iBAAiB;AACvE,SAAS,YAAY,mBAAmB;AACxC,SAAS,sBAAsB;AAExB,MAAM,kBAAkB,WAG7B,CAAC,EAAE,IAAI,MAAM,UAAU,GAAG,QAAQ;AACnC,QAAM,SAAS,UAAU;AAEzB,QAAM,gBAAgB;AAAA,IACrB,CAAC,MAA6C;AAC7C,UAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,YAAY,aAAa;AAGpD,2BAAmB,CAAC;AACpB,UAAE,cAAc,KAAK;AACrB,eAAO,gBAAgB,IAAI;AAAA,MAC5B;AAAA,IACD;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AAEA,QAAM,aAAa;AAAA,IAClB,CAAC,MAA0C;AAC1C,YAAM,QAAQ,OAAO,SAAuB,EAAE;AAC9C,UAAI,CAAC,MAAO;AAEZ,YAAMA,QAAO,MAAM,MAAM;AACzB,YAAM,QAAQ,EAAE,cAAc,MAAM,KAAK;AACzC,UAAIA,UAAS,MAAO;AAEpB,aAAO,aAAa;AAAA,QACnB;AAAA,UACC;AAAA,UACA,MAAM;AAAA,UACN,OAAO,EAAE,MAAM,MAAM;AAAA,QACtB;AAAA,MACD,CAAC;AAAA,IACF;AAAA,IACA,CAAC,IAAI,MAAM;AAAA,EACZ;AAEA,QAAM,eAAe;AAAA,IACpB,CAAC,MAA2C;AAC3C,YAAM,QAAQ,OAAO,SAAuB,EAAE;AAC9C,UAAI,CAAC,MAAO;AAEZ,YAAMA,QAAO,MAAM,MAAM;AACzB,YAAM,QAAQ,EAAE,cAAc;AAC9B,UAAIA,UAAS,MAAO;AAEpB,aAAO,aAAa;AAAA,QACnB;AAAA,UACC;AAAA,UACA,MAAM;AAAA,UACN,OAAO,EAAE,MAAM,MAAM;AAAA,QACtB;AAAA,MACD,CAAC;AAAA,IACF;AAAA,IACA,CAAC,IAAI,MAAM;AAAA,EACZ;AAEA,SACC,qBAAC,SAAI,WAAW,kBAAkB,YAAY,4BAA4B,EAAE,IAC3E;AAAA;AAAA,MAAC;AAAA;AAAA,QACA,WAAU;AAAA,QACV;AAAA,QACA,UAAU,CAAC;AAAA,QACX,UAAU,CAAC;AAAA,QACX,OAAO,EAAE,SAAS,YAAY,SAAY,OAAO;AAAA,QACjD,OAAO;AAAA,QACP,WAAS;AAAA,QACT,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,eAAe,YAAY,qBAAqB;AAAA,QAChD,WAAW;AAAA;AAAA,IACZ;AAAA,IACC,eAAe,MAAM,OAAO,IAAI,OAAO,aAAa,IAAI;AAAA,KAC1D;AAEF,CAAC;",
4
+ "sourcesContent": ["import { TLFrameShape, TLShapeId, useEditor } from '@tldraw/editor'\nimport { forwardRef, useCallback } from 'react'\nimport { defaultEmptyAs } from '../FrameShapeUtil'\n\nexport const FrameLabelInput = forwardRef<\n\tHTMLInputElement,\n\t{ id: TLShapeId; name: string; isEditing: boolean }\n>(({ id, name, isEditing }, ref) => {\n\tconst editor = useEditor()\n\n\tconst handlePointerDown = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\tif (isEditing) editor.markEventAsHandled(e)\n\t\t},\n\t\t[editor, isEditing]\n\t)\n\n\tconst handleKeyDown = useCallback(\n\t\t(e: React.KeyboardEvent<HTMLInputElement>) => {\n\t\t\tif (e.key === 'Enter' && !e.nativeEvent.isComposing) {\n\t\t\t\t// need to prevent the enter keydown making it's way up to the Idle state\n\t\t\t\t// and sending us back into edit mode\n\t\t\t\teditor.markEventAsHandled(e)\n\t\t\t\te.currentTarget.blur()\n\t\t\t\teditor.setEditingShape(null)\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst handleBlur = useCallback(\n\t\t(e: React.FocusEvent<HTMLInputElement>) => {\n\t\t\tconst shape = editor.getShape<TLFrameShape>(id)\n\t\t\tif (!shape) return\n\n\t\t\tconst name = shape.props.name\n\t\t\tconst value = e.currentTarget.value.trim()\n\t\t\tif (name === value) return\n\n\t\t\teditor.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: 'frame',\n\t\t\t\t\tprops: { name: value },\n\t\t\t\t},\n\t\t\t])\n\t\t},\n\t\t[id, editor]\n\t)\n\n\tconst handleChange = useCallback(\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst shape = editor.getShape<TLFrameShape>(id)\n\t\t\tif (!shape) return\n\n\t\t\tconst name = shape.props.name\n\t\t\tconst value = e.currentTarget.value\n\t\t\tif (name === value) return\n\n\t\t\teditor.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: 'frame',\n\t\t\t\t\tprops: { name: value },\n\t\t\t\t},\n\t\t\t])\n\t\t},\n\t\t[id, editor]\n\t)\n\n\treturn (\n\t\t<div className={`tl-frame-label ${isEditing ? 'tl-frame-label__editing' : ''}`}>\n\t\t\t<input\n\t\t\t\tclassName=\"tl-frame-name-input\"\n\t\t\t\tref={ref}\n\t\t\t\tdisabled={!isEditing}\n\t\t\t\treadOnly={!isEditing}\n\t\t\t\tstyle={{ display: isEditing ? undefined : 'none' }}\n\t\t\t\tvalue={name}\n\t\t\t\tautoFocus\n\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\tonBlur={handleBlur}\n\t\t\t\tonChange={handleChange}\n\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\tdraggable={false}\n\t\t\t/>\n\t\t\t{defaultEmptyAs(name, 'Frame') + String.fromCharCode(8203)}\n\t\t</div>\n\t)\n})\n"],
5
+ "mappings": "AAuEE,SACC,KADD;AAvEF,SAAkC,iBAAiB;AACnD,SAAS,YAAY,mBAAmB;AACxC,SAAS,sBAAsB;AAExB,MAAM,kBAAkB,WAG7B,CAAC,EAAE,IAAI,MAAM,UAAU,GAAG,QAAQ;AACnC,QAAM,SAAS,UAAU;AAEzB,QAAM,oBAAoB;AAAA,IACzB,CAAC,MAA0B;AAC1B,UAAI,UAAW,QAAO,mBAAmB,CAAC;AAAA,IAC3C;AAAA,IACA,CAAC,QAAQ,SAAS;AAAA,EACnB;AAEA,QAAM,gBAAgB;AAAA,IACrB,CAAC,MAA6C;AAC7C,UAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,YAAY,aAAa;AAGpD,eAAO,mBAAmB,CAAC;AAC3B,UAAE,cAAc,KAAK;AACrB,eAAO,gBAAgB,IAAI;AAAA,MAC5B;AAAA,IACD;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AAEA,QAAM,aAAa;AAAA,IAClB,CAAC,MAA0C;AAC1C,YAAM,QAAQ,OAAO,SAAuB,EAAE;AAC9C,UAAI,CAAC,MAAO;AAEZ,YAAMA,QAAO,MAAM,MAAM;AACzB,YAAM,QAAQ,EAAE,cAAc,MAAM,KAAK;AACzC,UAAIA,UAAS,MAAO;AAEpB,aAAO,aAAa;AAAA,QACnB;AAAA,UACC;AAAA,UACA,MAAM;AAAA,UACN,OAAO,EAAE,MAAM,MAAM;AAAA,QACtB;AAAA,MACD,CAAC;AAAA,IACF;AAAA,IACA,CAAC,IAAI,MAAM;AAAA,EACZ;AAEA,QAAM,eAAe;AAAA,IACpB,CAAC,MAA2C;AAC3C,YAAM,QAAQ,OAAO,SAAuB,EAAE;AAC9C,UAAI,CAAC,MAAO;AAEZ,YAAMA,QAAO,MAAM,MAAM;AACzB,YAAM,QAAQ,EAAE,cAAc;AAC9B,UAAIA,UAAS,MAAO;AAEpB,aAAO,aAAa;AAAA,QACnB;AAAA,UACC;AAAA,UACA,MAAM;AAAA,UACN,OAAO,EAAE,MAAM,MAAM;AAAA,QACtB;AAAA,MACD,CAAC;AAAA,IACF;AAAA,IACA,CAAC,IAAI,MAAM;AAAA,EACZ;AAEA,SACC,qBAAC,SAAI,WAAW,kBAAkB,YAAY,4BAA4B,EAAE,IAC3E;AAAA;AAAA,MAAC;AAAA;AAAA,QACA,WAAU;AAAA,QACV;AAAA,QACA,UAAU,CAAC;AAAA,QACX,UAAU,CAAC;AAAA,QACX,OAAO,EAAE,SAAS,YAAY,SAAY,OAAO;AAAA,QACjD,OAAO;AAAA,QACP,WAAS;AAAA,QACT,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,eAAe;AAAA,QACf,WAAW;AAAA;AAAA,IACZ;AAAA,IACC,eAAe,MAAM,OAAO,IAAI,OAAO,aAAa,IAAI;AAAA,KAC1D;AAEF,CAAC;",
6
6
  "names": ["name"]
7
7
  }
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { markEventAsHandled, useEditor, useValue } from "@tldraw/editor";
2
+ import { useEditor, useValue } from "@tldraw/editor";
3
3
  import classNames from "classnames";
4
4
  import { useCallback } from "react";
5
5
  const LINK_ICON = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' fill='none'%3E%3Cpath stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 5H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6M19 5h6m0 0v6m0-6L13 17'/%3E%3C/svg%3E";
@@ -8,7 +8,7 @@ function HyperlinkButton({ url }) {
8
8
  const hideButton = useValue("zoomLevel", () => editor.getZoomLevel() < 0.32, [editor]);
9
9
  const markAsHandledOnShiftKey = useCallback(
10
10
  (e) => {
11
- if (!editor.inputs.shiftKey) markEventAsHandled(e);
11
+ if (!editor.inputs.shiftKey) editor.markEventAsHandled(e);
12
12
  },
13
13
  [editor]
14
14
  );
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/HyperlinkButton.tsx"],
4
- "sourcesContent": ["import { markEventAsHandled, useEditor, useValue } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { PointerEventHandler, useCallback } from 'react'\n\nconst LINK_ICON =\n\t\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' fill='none'%3E%3Cpath stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 5H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6M19 5h6m0 0v6m0-6L13 17'/%3E%3C/svg%3E\"\n\nexport function HyperlinkButton({ url }: { url: string }) {\n\tconst editor = useEditor()\n\tconst hideButton = useValue('zoomLevel', () => editor.getZoomLevel() < 0.32, [editor])\n\tconst markAsHandledOnShiftKey = useCallback<PointerEventHandler>(\n\t\t(e) => {\n\t\t\tif (!editor.inputs.shiftKey) markEventAsHandled(e)\n\t\t},\n\t\t[editor]\n\t)\n\treturn (\n\t\t<a\n\t\t\tclassName={classNames('tl-hyperlink-button', {\n\t\t\t\t'tl-hyperlink-button__hidden': hideButton,\n\t\t\t})}\n\t\t\thref={url}\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer\"\n\t\t\tonPointerDown={markAsHandledOnShiftKey}\n\t\t\tonPointerUp={markAsHandledOnShiftKey}\n\t\t\ttitle={url}\n\t\t\tdraggable={false}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName=\"tl-hyperlink__icon\"\n\t\t\t\tstyle={{\n\t\t\t\t\tmask: `url(\"${LINK_ICON}\") center 100% / 100% no-repeat`,\n\t\t\t\t\tWebkitMask: `url(\"${LINK_ICON}\") center 100% / 100% no-repeat`,\n\t\t\t\t}}\n\t\t\t/>\n\t\t</a>\n\t)\n}\n"],
5
- "mappings": "AA6BG;AA7BH,SAAS,oBAAoB,WAAW,gBAAgB;AACxD,OAAO,gBAAgB;AACvB,SAA8B,mBAAmB;AAEjD,MAAM,YACL;AAEM,SAAS,gBAAgB,EAAE,IAAI,GAAoB;AACzD,QAAM,SAAS,UAAU;AACzB,QAAM,aAAa,SAAS,aAAa,MAAM,OAAO,aAAa,IAAI,MAAM,CAAC,MAAM,CAAC;AACrF,QAAM,0BAA0B;AAAA,IAC/B,CAAC,MAAM;AACN,UAAI,CAAC,OAAO,OAAO,SAAU,oBAAmB,CAAC;AAAA,IAClD;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AACA,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAW,WAAW,uBAAuB;AAAA,QAC5C,+BAA+B;AAAA,MAChC,CAAC;AAAA,MACD,MAAM;AAAA,MACN,QAAO;AAAA,MACP,KAAI;AAAA,MACJ,eAAe;AAAA,MACf,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,MAEX;AAAA,QAAC;AAAA;AAAA,UACA,WAAU;AAAA,UACV,OAAO;AAAA,YACN,MAAM,QAAQ,SAAS;AAAA,YACvB,YAAY,QAAQ,SAAS;AAAA,UAC9B;AAAA;AAAA,MACD;AAAA;AAAA,EACD;AAEF;",
4
+ "sourcesContent": ["import { useEditor, useValue } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { PointerEventHandler, useCallback } from 'react'\n\nconst LINK_ICON =\n\t\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' fill='none'%3E%3Cpath stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 5H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6M19 5h6m0 0v6m0-6L13 17'/%3E%3C/svg%3E\"\n\nexport function HyperlinkButton({ url }: { url: string }) {\n\tconst editor = useEditor()\n\tconst hideButton = useValue('zoomLevel', () => editor.getZoomLevel() < 0.32, [editor])\n\tconst markAsHandledOnShiftKey = useCallback<PointerEventHandler>(\n\t\t(e) => {\n\t\t\tif (!editor.inputs.shiftKey) editor.markEventAsHandled(e)\n\t\t},\n\t\t[editor]\n\t)\n\treturn (\n\t\t<a\n\t\t\tclassName={classNames('tl-hyperlink-button', {\n\t\t\t\t'tl-hyperlink-button__hidden': hideButton,\n\t\t\t})}\n\t\t\thref={url}\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer\"\n\t\t\tonPointerDown={markAsHandledOnShiftKey}\n\t\t\tonPointerUp={markAsHandledOnShiftKey}\n\t\t\ttitle={url}\n\t\t\tdraggable={false}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName=\"tl-hyperlink__icon\"\n\t\t\t\tstyle={{\n\t\t\t\t\tmask: `url(\"${LINK_ICON}\") center 100% / 100% no-repeat`,\n\t\t\t\t\tWebkitMask: `url(\"${LINK_ICON}\") center 100% / 100% no-repeat`,\n\t\t\t\t}}\n\t\t\t/>\n\t\t</a>\n\t)\n}\n"],
5
+ "mappings": "AA6BG;AA7BH,SAAS,WAAW,gBAAgB;AACpC,OAAO,gBAAgB;AACvB,SAA8B,mBAAmB;AAEjD,MAAM,YACL;AAEM,SAAS,gBAAgB,EAAE,IAAI,GAAoB;AACzD,QAAM,SAAS,UAAU;AACzB,QAAM,aAAa,SAAS,aAAa,MAAM,OAAO,aAAa,IAAI,MAAM,CAAC,MAAM,CAAC;AACrF,QAAM,0BAA0B;AAAA,IAC/B,CAAC,MAAM;AACN,UAAI,CAAC,OAAO,OAAO,SAAU,QAAO,mBAAmB,CAAC;AAAA,IACzD;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AACA,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAW,WAAW,uBAAuB;AAAA,QAC5C,+BAA+B;AAAA,MAChC,CAAC;AAAA,MACD,MAAM;AAAA,MACN,QAAO;AAAA,MACP,KAAI;AAAA,MACJ,eAAe;AAAA,MACf,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,MAEX;AAAA,QAAC;AAAA;AAAA,UACA,WAAU;AAAA,UACV,OAAO;AAAA,YACN,MAAM,QAAQ,SAAS;AAAA,YACvB,YAAY,QAAQ,SAAS;AAAA,UAC9B;AAAA;AAAA,MACD;AAAA;AAAA,EACD;AAEF;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  getPointerInfo,
3
- markEventAsHandled,
4
3
  noop,
5
4
  preventDefault,
6
5
  tlenv,
@@ -93,7 +92,7 @@ function useEditableTextCommon(shapeId) {
93
92
  const handleInputPointerDown = useCallback(
94
93
  (e) => {
95
94
  editor.dispatch({
96
- ...getPointerInfo(e),
95
+ ...getPointerInfo(editor, e),
97
96
  type: "pointer",
98
97
  name: "pointer_down",
99
98
  target: "shape",
@@ -117,12 +116,11 @@ function useEditableTextCommon(shapeId) {
117
116
  },
118
117
  [editor, shapeId]
119
118
  );
120
- const handleDoubleClick = markEventAsHandled;
121
119
  return {
122
120
  handleFocus: noop,
123
121
  handleBlur: noop,
124
122
  handleInputPointerDown,
125
- handleDoubleClick,
123
+ handleDoubleClick: editor.markEventAsHandled,
126
124
  handlePaste,
127
125
  isEditing,
128
126
  isReadyForEditing
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/useEditablePlainText.ts"],
4
- "sourcesContent": ["import {\n\tEditor,\n\tTLShapeId,\n\tTLUnknownShape,\n\tgetPointerInfo,\n\tmarkEventAsHandled,\n\tnoop,\n\tpreventDefault,\n\ttlenv,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport React, { useCallback, useEffect, useRef } from 'react'\nimport { TextHelpers } from './TextHelpers'\n\n/** @public */\nexport function useEditablePlainText(shapeId: TLShapeId, type: string, text?: string) {\n\tconst commonUseEditableTextHandlers = useEditableTextCommon(shapeId)\n\tconst isEditing = commonUseEditableTextHandlers.isEditing\n\tconst editor = useEditor()\n\tconst rInput = useRef<HTMLTextAreaElement>(null)\n\tconst isEmpty = (text || '').trim().length === 0\n\n\tuseEffect(() => {\n\t\tfunction selectAllIfEditing(event: { shapeId: TLShapeId }) {\n\t\t\tif (event.shapeId === shapeId) {\n\t\t\t\trInput.current?.select?.()\n\t\t\t}\n\t\t}\n\n\t\teditor.on('select-all-text', selectAllIfEditing)\n\t\treturn () => {\n\t\t\teditor.off('select-all-text', selectAllIfEditing)\n\t\t}\n\t}, [editor, shapeId, isEditing])\n\n\tuseEffect(() => {\n\t\tif (!isEditing) return\n\n\t\tif (document.activeElement !== rInput.current) {\n\t\t\trInput.current?.focus()\n\t\t}\n\n\t\tif (editor.getInstanceState().isCoarsePointer) {\n\t\t\trInput.current?.select()\n\t\t}\n\n\t\t// XXX(mime): This fixes iOS not showing the caret sometimes.\n\t\t// This \"shakes\" the caret awake.\n\t\tif (tlenv.isSafari) {\n\t\t\trInput.current?.blur()\n\t\t\trInput.current?.focus()\n\t\t}\n\t}, [editor, isEditing])\n\n\t// When the user presses ctrl / meta enter, complete the editing state.\n\tconst handleKeyDown = useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase 'Enter': {\n\t\t\t\t\tif (e.ctrlKey || e.metaKey) {\n\t\t\t\t\t\teditor.complete()\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\t// When the text changes, update the text value.\n\tconst handleChange = useCallback(\n\t\t({ plaintext }: { plaintext: string }) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\n\t\t\tconst normalizedPlaintext = TextHelpers.normalizeText(plaintext || '')\n\t\t\teditor.updateShape<TLUnknownShape & { props: { text: string } }>({\n\t\t\t\tid: shapeId,\n\t\t\t\ttype,\n\t\t\t\tprops: { text: normalizedPlaintext },\n\t\t\t})\n\t\t},\n\t\t[editor, shapeId, type]\n\t)\n\n\treturn {\n\t\trInput,\n\t\thandleKeyDown,\n\t\thandleChange,\n\t\tisEmpty,\n\t\t...commonUseEditableTextHandlers,\n\t}\n}\n\n/** @internal */\nexport function useIsReadyForEditing(editor: Editor, shapeId: TLShapeId) {\n\treturn useValue(\n\t\t'isReadyForEditing',\n\t\t() => {\n\t\t\tconst editingShapeId = editor.getEditingShapeId()\n\t\t\treturn (\n\t\t\t\t// something's being editing... and either it's this shape OR this shape is hovered\n\t\t\t\teditingShapeId !== null &&\n\t\t\t\t(editingShapeId === shapeId || editor.getHoveredShapeId() === shapeId)\n\t\t\t)\n\t\t},\n\t\t[editor, shapeId]\n\t)\n}\n\n/** @internal */\nexport function useEditableTextCommon(shapeId: TLShapeId) {\n\tconst editor = useEditor()\n\tconst isEditing = useValue('isEditing', () => editor.getEditingShapeId() === shapeId, [editor])\n\tconst isReadyForEditing = useIsReadyForEditing(editor, shapeId)\n\n\tconst handleInputPointerDown = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\t// N.B. We used to only do this only when isEditing to help\n\t\t\t// prevent an issue where you could drag a selected shape\n\t\t\t// behind another shape. That is addressed now by the CSS logic\n\t\t\t// looking at data-isselectinganything.\n\t\t\t//\n\t\t\t// We still need to follow this logic even if not isEditing\n\t\t\t// because otherwise there is some flakiness in selection.\n\t\t\t// When selecting text, it would sometimes select some text\n\t\t\t// partially if we didn't dispatch/stop below.\n\n\t\t\teditor.dispatch({\n\t\t\t\t...getPointerInfo(e),\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_down',\n\t\t\t\ttarget: 'shape',\n\t\t\t\tshape: editor.getShape(shapeId)!,\n\t\t\t})\n\n\t\t\te.stopPropagation() // we need to prevent blurring the input\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\tconst handlePaste = useCallback(\n\t\t(e: ClipboardEvent | React.ClipboardEvent<HTMLTextAreaElement>) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\t\t\tif (e.clipboardData) {\n\t\t\t\t// find html in the clipboard and look for the tldraw data\n\t\t\t\tconst html = e.clipboardData.getData('text/html')\n\t\t\t\tif (html) {\n\t\t\t\t\tif (html.includes('<div data-tldraw')) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\tconst handleDoubleClick: (e: React.MouseEvent) => void = markEventAsHandled\n\n\treturn {\n\t\thandleFocus: noop,\n\t\thandleBlur: noop,\n\t\thandleInputPointerDown,\n\t\thandleDoubleClick,\n\t\thandlePaste,\n\t\tisEditing,\n\t\tisReadyForEditing,\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tEditor,\n\tTLShapeId,\n\tTLUnknownShape,\n\tgetPointerInfo,\n\tnoop,\n\tpreventDefault,\n\ttlenv,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport React, { useCallback, useEffect, useRef } from 'react'\nimport { TextHelpers } from './TextHelpers'\n\n/** @public */\nexport function useEditablePlainText(shapeId: TLShapeId, type: string, text?: string) {\n\tconst commonUseEditableTextHandlers = useEditableTextCommon(shapeId)\n\tconst isEditing = commonUseEditableTextHandlers.isEditing\n\tconst editor = useEditor()\n\tconst rInput = useRef<HTMLTextAreaElement>(null)\n\tconst isEmpty = (text || '').trim().length === 0\n\n\tuseEffect(() => {\n\t\tfunction selectAllIfEditing(event: { shapeId: TLShapeId }) {\n\t\t\tif (event.shapeId === shapeId) {\n\t\t\t\trInput.current?.select?.()\n\t\t\t}\n\t\t}\n\n\t\teditor.on('select-all-text', selectAllIfEditing)\n\t\treturn () => {\n\t\t\teditor.off('select-all-text', selectAllIfEditing)\n\t\t}\n\t}, [editor, shapeId, isEditing])\n\n\tuseEffect(() => {\n\t\tif (!isEditing) return\n\n\t\tif (document.activeElement !== rInput.current) {\n\t\t\trInput.current?.focus()\n\t\t}\n\n\t\tif (editor.getInstanceState().isCoarsePointer) {\n\t\t\trInput.current?.select()\n\t\t}\n\n\t\t// XXX(mime): This fixes iOS not showing the caret sometimes.\n\t\t// This \"shakes\" the caret awake.\n\t\tif (tlenv.isSafari) {\n\t\t\trInput.current?.blur()\n\t\t\trInput.current?.focus()\n\t\t}\n\t}, [editor, isEditing])\n\n\t// When the user presses ctrl / meta enter, complete the editing state.\n\tconst handleKeyDown = useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase 'Enter': {\n\t\t\t\t\tif (e.ctrlKey || e.metaKey) {\n\t\t\t\t\t\teditor.complete()\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\t// When the text changes, update the text value.\n\tconst handleChange = useCallback(\n\t\t({ plaintext }: { plaintext: string }) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\n\t\t\tconst normalizedPlaintext = TextHelpers.normalizeText(plaintext || '')\n\t\t\teditor.updateShape<TLUnknownShape & { props: { text: string } }>({\n\t\t\t\tid: shapeId,\n\t\t\t\ttype,\n\t\t\t\tprops: { text: normalizedPlaintext },\n\t\t\t})\n\t\t},\n\t\t[editor, shapeId, type]\n\t)\n\n\treturn {\n\t\trInput,\n\t\thandleKeyDown,\n\t\thandleChange,\n\t\tisEmpty,\n\t\t...commonUseEditableTextHandlers,\n\t}\n}\n\n/** @internal */\nexport function useIsReadyForEditing(editor: Editor, shapeId: TLShapeId) {\n\treturn useValue(\n\t\t'isReadyForEditing',\n\t\t() => {\n\t\t\tconst editingShapeId = editor.getEditingShapeId()\n\t\t\treturn (\n\t\t\t\t// something's being editing... and either it's this shape OR this shape is hovered\n\t\t\t\teditingShapeId !== null &&\n\t\t\t\t(editingShapeId === shapeId || editor.getHoveredShapeId() === shapeId)\n\t\t\t)\n\t\t},\n\t\t[editor, shapeId]\n\t)\n}\n\n/** @internal */\nexport function useEditableTextCommon(shapeId: TLShapeId) {\n\tconst editor = useEditor()\n\tconst isEditing = useValue('isEditing', () => editor.getEditingShapeId() === shapeId, [editor])\n\tconst isReadyForEditing = useIsReadyForEditing(editor, shapeId)\n\n\tconst handleInputPointerDown = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\t// N.B. We used to only do this only when isEditing to help\n\t\t\t// prevent an issue where you could drag a selected shape\n\t\t\t// behind another shape. That is addressed now by the CSS logic\n\t\t\t// looking at data-isselectinganything.\n\t\t\t//\n\t\t\t// We still need to follow this logic even if not isEditing\n\t\t\t// because otherwise there is some flakiness in selection.\n\t\t\t// When selecting text, it would sometimes select some text\n\t\t\t// partially if we didn't dispatch/stop below.\n\n\t\t\teditor.dispatch({\n\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_down',\n\t\t\t\ttarget: 'shape',\n\t\t\t\tshape: editor.getShape(shapeId)!,\n\t\t\t})\n\n\t\t\te.stopPropagation() // we need to prevent blurring the input\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\tconst handlePaste = useCallback(\n\t\t(e: ClipboardEvent | React.ClipboardEvent<HTMLTextAreaElement>) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\t\t\tif (e.clipboardData) {\n\t\t\t\t// find html in the clipboard and look for the tldraw data\n\t\t\t\tconst html = e.clipboardData.getData('text/html')\n\t\t\t\tif (html) {\n\t\t\t\t\tif (html.includes('<div data-tldraw')) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\treturn {\n\t\thandleFocus: noop,\n\t\thandleBlur: noop,\n\t\thandleInputPointerDown,\n\t\thandleDoubleClick: editor.markEventAsHandled,\n\t\thandlePaste,\n\t\tisEditing,\n\t\tisReadyForEditing,\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { markEventAsHandled, preventDefault } from "@tldraw/editor";
2
+ import { preventDefault, useEditor } from "@tldraw/editor";
3
3
  import React from "react";
4
4
  const PlainTextArea = React.forwardRef(function TextArea({
5
5
  isEditing,
@@ -12,6 +12,7 @@ const PlainTextArea = React.forwardRef(function TextArea({
12
12
  handleInputPointerDown,
13
13
  handleDoubleClick
14
14
  }, ref) {
15
+ const editor = useEditor();
15
16
  const onChange = (e) => {
16
17
  handleChange({ plaintext: e.target.value });
17
18
  };
@@ -37,7 +38,7 @@ const PlainTextArea = React.forwardRef(function TextArea({
37
38
  onChange,
38
39
  onKeyDown: (e) => handleKeyDown(e.nativeEvent),
39
40
  onBlur: handleBlur,
40
- onTouchEnd: markEventAsHandled,
41
+ onTouchEnd: editor.markEventAsHandled,
41
42
  onContextMenu: isEditing ? (e) => e.stopPropagation() : void 0,
42
43
  onPointerDown: handleInputPointerDown,
43
44
  onPaste: handlePaste,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/text/PlainTextArea.tsx"],
4
- "sourcesContent": ["import { markEventAsHandled, preventDefault } from '@tldraw/editor'\nimport React from 'react'\nimport { TextAreaProps } from './RichTextArea'\n\n/**\n * A plain text area that can be used for basic editing text.\n *\n * @public @react\n */\nexport const PlainTextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(function TextArea(\n\t{\n\t\tisEditing,\n\t\ttext,\n\t\thandleFocus,\n\t\thandleChange,\n\t\thandleKeyDown,\n\t\thandlePaste,\n\t\thandleBlur,\n\t\thandleInputPointerDown,\n\t\thandleDoubleClick,\n\t},\n\tref\n) {\n\tconst onChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n\t\thandleChange({ plaintext: e.target.value })\n\t}\n\n\treturn (\n\t\t<textarea\n\t\t\tref={ref}\n\t\t\tclassName=\"tl-text tl-text-input\"\n\t\t\tname=\"text\"\n\t\t\ttabIndex={-1}\n\t\t\tdisabled={!isEditing}\n\t\t\treadOnly={!isEditing}\n\t\t\tautoComplete=\"off\"\n\t\t\tautoCapitalize=\"off\"\n\t\t\tautoCorrect=\"off\"\n\t\t\tautoSave=\"off\"\n\t\t\tplaceholder=\"\"\n\t\t\tspellCheck=\"true\"\n\t\t\twrap=\"off\"\n\t\t\tdir=\"auto\"\n\t\t\tdefaultValue={text}\n\t\t\tonFocus={handleFocus}\n\t\t\tonChange={onChange}\n\t\t\tonKeyDown={(e) => handleKeyDown(e.nativeEvent)}\n\t\t\tonBlur={handleBlur}\n\t\t\tonTouchEnd={markEventAsHandled}\n\t\t\tonContextMenu={isEditing ? (e) => e.stopPropagation() : undefined}\n\t\t\tonPointerDown={handleInputPointerDown}\n\t\t\tonPaste={handlePaste}\n\t\t\tonDoubleClick={handleDoubleClick}\n\t\t\t// On FF, there's a behavior where dragging a selection will grab that selection into\n\t\t\t// the drag event. However, once the drag is over, and you select away from the textarea,\n\t\t\t// starting a drag over the textarea will restart a selection drag instead of a shape drag.\n\t\t\t// This prevents that default behavior in FF.\n\t\t\tonDragStart={preventDefault}\n\t\t/>\n\t)\n})\n"],
5
- "mappings": "AA4BE;AA5BF,SAAS,oBAAoB,sBAAsB;AACnD,OAAO,WAAW;AAQX,MAAM,gBAAgB,MAAM,WAA+C,SAAS,SAC1F;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GACA,KACC;AACD,QAAM,WAAW,CAAC,MAA8C;AAC/D,iBAAa,EAAE,WAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3C;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA;AAAA,MACA,WAAU;AAAA,MACV,MAAK;AAAA,MACL,UAAU;AAAA,MACV,UAAU,CAAC;AAAA,MACX,UAAU,CAAC;AAAA,MACX,cAAa;AAAA,MACb,gBAAe;AAAA,MACf,aAAY;AAAA,MACZ,UAAS;AAAA,MACT,aAAY;AAAA,MACZ,YAAW;AAAA,MACX,MAAK;AAAA,MACL,KAAI;AAAA,MACJ,cAAc;AAAA,MACd,SAAS;AAAA,MACT;AAAA,MACA,WAAW,CAAC,MAAM,cAAc,EAAE,WAAW;AAAA,MAC7C,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,eAAe,YAAY,CAAC,MAAM,EAAE,gBAAgB,IAAI;AAAA,MACxD,eAAe;AAAA,MACf,SAAS;AAAA,MACT,eAAe;AAAA,MAKf,aAAa;AAAA;AAAA,EACd;AAEF,CAAC;",
4
+ "sourcesContent": ["import { preventDefault, useEditor } from '@tldraw/editor'\nimport React from 'react'\nimport { TextAreaProps } from './RichTextArea'\n\n/**\n * A plain text area that can be used for basic editing text.\n *\n * @public @react\n */\nexport const PlainTextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(function TextArea(\n\t{\n\t\tisEditing,\n\t\ttext,\n\t\thandleFocus,\n\t\thandleChange,\n\t\thandleKeyDown,\n\t\thandlePaste,\n\t\thandleBlur,\n\t\thandleInputPointerDown,\n\t\thandleDoubleClick,\n\t},\n\tref\n) {\n\tconst editor = useEditor()\n\tconst onChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n\t\thandleChange({ plaintext: e.target.value })\n\t}\n\n\treturn (\n\t\t<textarea\n\t\t\tref={ref}\n\t\t\tclassName=\"tl-text tl-text-input\"\n\t\t\tname=\"text\"\n\t\t\ttabIndex={-1}\n\t\t\tdisabled={!isEditing}\n\t\t\treadOnly={!isEditing}\n\t\t\tautoComplete=\"off\"\n\t\t\tautoCapitalize=\"off\"\n\t\t\tautoCorrect=\"off\"\n\t\t\tautoSave=\"off\"\n\t\t\tplaceholder=\"\"\n\t\t\tspellCheck=\"true\"\n\t\t\twrap=\"off\"\n\t\t\tdir=\"auto\"\n\t\t\tdefaultValue={text}\n\t\t\tonFocus={handleFocus}\n\t\t\tonChange={onChange}\n\t\t\tonKeyDown={(e) => handleKeyDown(e.nativeEvent)}\n\t\t\tonBlur={handleBlur}\n\t\t\tonTouchEnd={editor.markEventAsHandled}\n\t\t\tonContextMenu={isEditing ? (e) => e.stopPropagation() : undefined}\n\t\t\tonPointerDown={handleInputPointerDown}\n\t\t\tonPaste={handlePaste}\n\t\t\tonDoubleClick={handleDoubleClick}\n\t\t\t// On FF, there's a behavior where dragging a selection will grab that selection into\n\t\t\t// the drag event. However, once the drag is over, and you select away from the textarea,\n\t\t\t// starting a drag over the textarea will restart a selection drag instead of a shape drag.\n\t\t\t// This prevents that default behavior in FF.\n\t\t\tonDragStart={preventDefault}\n\t\t/>\n\t)\n})\n"],
5
+ "mappings": "AA6BE;AA7BF,SAAS,gBAAgB,iBAAiB;AAC1C,OAAO,WAAW;AAQX,MAAM,gBAAgB,MAAM,WAA+C,SAAS,SAC1F;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GACA,KACC;AACD,QAAM,SAAS,UAAU;AACzB,QAAM,WAAW,CAAC,MAA8C;AAC/D,iBAAa,EAAE,WAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3C;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA;AAAA,MACA,WAAU;AAAA,MACV,MAAK;AAAA,MACL,UAAU;AAAA,MACV,UAAU,CAAC;AAAA,MACX,UAAU,CAAC;AAAA,MACX,cAAa;AAAA,MACb,gBAAe;AAAA,MACf,aAAY;AAAA,MACZ,UAAS;AAAA,MACT,aAAY;AAAA,MACZ,YAAW;AAAA,MACX,MAAK;AAAA,MACL,KAAI;AAAA,MACJ,cAAc;AAAA,MACd,SAAS;AAAA,MACT;AAAA,MACA,WAAW,CAAC,MAAM,cAAc,EAAE,WAAW;AAAA,MAC7C,QAAQ;AAAA,MACR,YAAY,OAAO;AAAA,MACnB,eAAe,YAAY,CAAC,MAAM,EAAE,gBAAgB,IAAI;AAAA,MACxD,eAAe;AAAA,MACf,SAAS;AAAA,MACT,eAAe;AAAA,MAKf,aAAa;AAAA;AAAA,EACd;AAEF,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import {
3
3
  debugFlags,
4
- markEventAsHandled,
5
4
  unsafe__withoutCapture,
6
5
  useContainer,
7
6
  useEditor,
@@ -19,7 +18,7 @@ function SkipToMainContent() {
19
18
  const button = useRef(null);
20
19
  const handleNavigateToFirstShape = useCallback(
21
20
  (e) => {
22
- markEventAsHandled(e);
21
+ editor.markEventAsHandled(e);
23
22
  button.current?.blur();
24
23
  const shapes = editor.getCurrentPageShapesInReadingOrder();
25
24
  if (!shapes.length) return;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/ui/components/A11y.tsx"],
4
- "sourcesContent": ["import {\n\tdebugFlags,\n\tEditor,\n\tmarkEventAsHandled,\n\tTLGeoShape,\n\tTLShapeId,\n\tunsafe__withoutCapture,\n\tuseContainer,\n\tuseEditor,\n\tuseMaybeEditor,\n\tuseReactor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { memo, MouseEvent, useCallback, useEffect, useRef } from 'react'\nimport { useA11y } from '../context/a11y'\nimport { useTranslation } from '../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from './primitives/Button/TldrawUiButton'\n\nexport function SkipToMainContent() {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\tconst button = useRef<HTMLButtonElement>(null)\n\n\tconst handleNavigateToFirstShape = useCallback(\n\t\t(e: MouseEvent | KeyboardEvent) => {\n\t\t\tmarkEventAsHandled(e)\n\t\t\tbutton.current?.blur()\n\t\t\tconst shapes = editor.getCurrentPageShapesInReadingOrder()\n\t\t\tif (!shapes.length) return\n\t\t\teditor.setSelectedShapes([shapes[0].id])\n\t\t\teditor.zoomToSelectionIfOffscreen(256, {\n\t\t\t\tanimation: {\n\t\t\t\t\tduration: editor.options.animationMediumMs,\n\t\t\t\t},\n\t\t\t\tinset: 0,\n\t\t\t})\n\n\t\t\t// N.B. If we don't do this, then we go into editing mode for some reason...\n\t\t\t// Not sure of a better solution at the moment...\n\t\t\teditor.timers.setTimeout(() => editor.getContainer().focus(), 100)\n\t\t},\n\t\t[editor]\n\t)\n\n\treturn (\n\t\t<TldrawUiButton\n\t\t\tref={button}\n\t\t\ttype=\"low\"\n\t\t\ttabIndex={0}\n\t\t\tclassName=\"tl-skip-to-main-content\"\n\t\t\tonClick={handleNavigateToFirstShape}\n\t\t>\n\t\t\t{msg('a11y.skip-to-main-content')}\n\t\t</TldrawUiButton>\n\t)\n}\n\n/** @public @react */\nexport const DefaultA11yAnnouncer = memo(function TldrawUiA11yAnnouncer() {\n\tconst a11y = useA11y()\n\tconst translation = useTranslation()\n\tconst msg = useValue('a11y-msg', () => a11y.currentMsg.get(), [])\n\tuseA11yDebug(msg.msg)\n\n\tuseSelectedShapesAnnouncer()\n\n\treturn (\n\t\tmsg.msg && (\n\t\t\t<div\n\t\t\t\taria-label={translation('a11y.status')}\n\t\t\t\taria-live={msg.priority || 'assertive'}\n\t\t\t\trole=\"status\"\n\t\t\t\taria-hidden=\"false\"\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\ttop: '-10000px',\n\t\t\t\t\tleft: '-10000px',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{msg.msg}\n\t\t\t</div>\n\t\t)\n\t)\n})\n\n/**\n * Core function to generate accessibility announcements for selected shapes\n * @public\n */\nexport function generateShapeAnnouncementMessage(args: {\n\teditor: Editor\n\tselectedShapeIds: TLShapeId[]\n\tmsg(id: string, values?: Record<string, any>): string\n}) {\n\tconst { editor, selectedShapeIds, msg } = args\n\tlet a11yLive = ''\n\tconst numShapes = selectedShapeIds.length\n\n\tif (numShapes > 1) {\n\t\ta11yLive = msg('a11y.multiple-shapes').replace('{num}', numShapes.toString())\n\t} else if (numShapes === 1) {\n\t\tconst shapeId = selectedShapeIds[0]\n\t\tconst shape = editor.getShape(shapeId)\n\t\tif (!shape) return ''\n\n\t\tconst shapeUtil = editor.getShapeUtil(shape.type)\n\n\t\tconst isMedia = ['image', 'video'].includes(shape.type)\n\t\t// Yeah, yeah this is a bit of a hack, we should get better translations.\n\t\tlet shapeType = ''\n\t\tif (shape.type === 'geo') {\n\t\t\tshapeType = msg(`geo-style.${(shape as TLGeoShape).props.geo}`)\n\t\t} else if (isMedia) {\n\t\t\tshapeType = msg(`a11y.shape-${shape.type}`)\n\t\t} else {\n\t\t\tshapeType = msg(`tool.${shape.type}`)\n\t\t}\n\n\t\t// Get shape index in reading order\n\t\tconst readingOrderShapes = editor.getCurrentPageShapesInReadingOrder()\n\t\tconst currentShapeIndex = (readingOrderShapes.findIndex((s) => s.id === shapeId) + 1).toString()\n\t\tconst totalShapes = readingOrderShapes.length.toString()\n\t\tconst shapeIndex = msg('a11y.shape-index')\n\t\t\t.replace('{num}', currentShapeIndex)\n\t\t\t.replace('{total}', totalShapes)\n\n\t\t// Get describing text (alt text or shape text)\n\t\tconst describingText = shapeUtil.getAriaDescriptor(shape) || shapeUtil.getText(shape) || ''\n\n\t\t// Build the full announcement\n\t\ta11yLive = (describingText ? `${describingText}, ` : '') + `${shapeType}. ${shapeIndex}`\n\t}\n\n\treturn a11yLive\n}\n\n/** @public */\nexport const useSelectedShapesAnnouncer = () => {\n\tconst editor = useMaybeEditor()\n\tconst a11y = useA11y()\n\tconst msg = useTranslation()\n\n\tconst rPrevSelectedShapeIds = useRef<string[]>([])\n\n\tuseReactor(\n\t\t'announce selection',\n\t\t() => {\n\t\t\tif (!editor) return\n\n\t\t\tconst isInSelecting = editor.isIn('select.idle')\n\t\t\tif (isInSelecting) {\n\t\t\t\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\t\t\t\tif (selectedShapeIds !== rPrevSelectedShapeIds.current) {\n\t\t\t\t\trPrevSelectedShapeIds.current = selectedShapeIds\n\t\t\t\t\tunsafe__withoutCapture(() => {\n\t\t\t\t\t\tconst a11yLive = generateShapeAnnouncementMessage({\n\t\t\t\t\t\t\teditor,\n\t\t\t\t\t\t\tselectedShapeIds,\n\t\t\t\t\t\t\tmsg,\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tif (a11yLive) {\n\t\t\t\t\t\t\ta11y.announce({ msg: a11yLive })\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, a11y, msg]\n\t)\n}\n\nconst useA11yDebug = (msg: string | undefined) => {\n\tconst container = useContainer()\n\n\tuseEffect(() => {\n\t\tif (debugFlags.a11y.get()) {\n\t\t\tconst log = (msg: string) => {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.debug(\n\t\t\t\t\t`%ca11y%c: ${msg}`,\n\t\t\t\t\t`color: white; background: #40C057; padding: 2px;border-radius: 3px;`,\n\t\t\t\t\t'font-weight: normal'\n\t\t\t\t)\n\t\t\t}\n\t\t\tconst handleKeyUp = (e: KeyboardEvent) => {\n\t\t\t\tconst el = document.activeElement\n\t\t\t\tif (\n\t\t\t\t\te.key === 'Tab' &&\n\t\t\t\t\tel &&\n\t\t\t\t\tel !== document.body &&\n\t\t\t\t\t!el.classList.contains('tl-container')\n\t\t\t\t) {\n\t\t\t\t\tconst label = el.getAttribute('aria-label') || el.getAttribute('title') || el.textContent\n\t\t\t\t\tif (label) {\n\t\t\t\t\t\tlog(label)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (msg) {\n\t\t\t\tlog(msg)\n\t\t\t}\n\n\t\t\tdocument.addEventListener('keyup', handleKeyUp)\n\t\t\treturn () => document.removeEventListener('keyup', handleKeyUp)\n\t\t}\n\t}, [container, msg])\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tdebugFlags,\n\tEditor,\n\tTLGeoShape,\n\tTLShapeId,\n\tunsafe__withoutCapture,\n\tuseContainer,\n\tuseEditor,\n\tuseMaybeEditor,\n\tuseReactor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { memo, MouseEvent, useCallback, useEffect, useRef } from 'react'\nimport { useA11y } from '../context/a11y'\nimport { useTranslation } from '../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from './primitives/Button/TldrawUiButton'\n\nexport function SkipToMainContent() {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\tconst button = useRef<HTMLButtonElement>(null)\n\n\tconst handleNavigateToFirstShape = useCallback(\n\t\t(e: MouseEvent | KeyboardEvent) => {\n\t\t\teditor.markEventAsHandled(e)\n\t\t\tbutton.current?.blur()\n\t\t\tconst shapes = editor.getCurrentPageShapesInReadingOrder()\n\t\t\tif (!shapes.length) return\n\t\t\teditor.setSelectedShapes([shapes[0].id])\n\t\t\teditor.zoomToSelectionIfOffscreen(256, {\n\t\t\t\tanimation: {\n\t\t\t\t\tduration: editor.options.animationMediumMs,\n\t\t\t\t},\n\t\t\t\tinset: 0,\n\t\t\t})\n\n\t\t\t// N.B. If we don't do this, then we go into editing mode for some reason...\n\t\t\t// Not sure of a better solution at the moment...\n\t\t\teditor.timers.setTimeout(() => editor.getContainer().focus(), 100)\n\t\t},\n\t\t[editor]\n\t)\n\n\treturn (\n\t\t<TldrawUiButton\n\t\t\tref={button}\n\t\t\ttype=\"low\"\n\t\t\ttabIndex={0}\n\t\t\tclassName=\"tl-skip-to-main-content\"\n\t\t\tonClick={handleNavigateToFirstShape}\n\t\t>\n\t\t\t{msg('a11y.skip-to-main-content')}\n\t\t</TldrawUiButton>\n\t)\n}\n\n/** @public @react */\nexport const DefaultA11yAnnouncer = memo(function TldrawUiA11yAnnouncer() {\n\tconst a11y = useA11y()\n\tconst translation = useTranslation()\n\tconst msg = useValue('a11y-msg', () => a11y.currentMsg.get(), [])\n\tuseA11yDebug(msg.msg)\n\n\tuseSelectedShapesAnnouncer()\n\n\treturn (\n\t\tmsg.msg && (\n\t\t\t<div\n\t\t\t\taria-label={translation('a11y.status')}\n\t\t\t\taria-live={msg.priority || 'assertive'}\n\t\t\t\trole=\"status\"\n\t\t\t\taria-hidden=\"false\"\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\ttop: '-10000px',\n\t\t\t\t\tleft: '-10000px',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{msg.msg}\n\t\t\t</div>\n\t\t)\n\t)\n})\n\n/**\n * Core function to generate accessibility announcements for selected shapes\n * @public\n */\nexport function generateShapeAnnouncementMessage(args: {\n\teditor: Editor\n\tselectedShapeIds: TLShapeId[]\n\tmsg(id: string, values?: Record<string, any>): string\n}) {\n\tconst { editor, selectedShapeIds, msg } = args\n\tlet a11yLive = ''\n\tconst numShapes = selectedShapeIds.length\n\n\tif (numShapes > 1) {\n\t\ta11yLive = msg('a11y.multiple-shapes').replace('{num}', numShapes.toString())\n\t} else if (numShapes === 1) {\n\t\tconst shapeId = selectedShapeIds[0]\n\t\tconst shape = editor.getShape(shapeId)\n\t\tif (!shape) return ''\n\n\t\tconst shapeUtil = editor.getShapeUtil(shape.type)\n\n\t\tconst isMedia = ['image', 'video'].includes(shape.type)\n\t\t// Yeah, yeah this is a bit of a hack, we should get better translations.\n\t\tlet shapeType = ''\n\t\tif (shape.type === 'geo') {\n\t\t\tshapeType = msg(`geo-style.${(shape as TLGeoShape).props.geo}`)\n\t\t} else if (isMedia) {\n\t\t\tshapeType = msg(`a11y.shape-${shape.type}`)\n\t\t} else {\n\t\t\tshapeType = msg(`tool.${shape.type}`)\n\t\t}\n\n\t\t// Get shape index in reading order\n\t\tconst readingOrderShapes = editor.getCurrentPageShapesInReadingOrder()\n\t\tconst currentShapeIndex = (readingOrderShapes.findIndex((s) => s.id === shapeId) + 1).toString()\n\t\tconst totalShapes = readingOrderShapes.length.toString()\n\t\tconst shapeIndex = msg('a11y.shape-index')\n\t\t\t.replace('{num}', currentShapeIndex)\n\t\t\t.replace('{total}', totalShapes)\n\n\t\t// Get describing text (alt text or shape text)\n\t\tconst describingText = shapeUtil.getAriaDescriptor(shape) || shapeUtil.getText(shape) || ''\n\n\t\t// Build the full announcement\n\t\ta11yLive = (describingText ? `${describingText}, ` : '') + `${shapeType}. ${shapeIndex}`\n\t}\n\n\treturn a11yLive\n}\n\n/** @public */\nexport const useSelectedShapesAnnouncer = () => {\n\tconst editor = useMaybeEditor()\n\tconst a11y = useA11y()\n\tconst msg = useTranslation()\n\n\tconst rPrevSelectedShapeIds = useRef<string[]>([])\n\n\tuseReactor(\n\t\t'announce selection',\n\t\t() => {\n\t\t\tif (!editor) return\n\n\t\t\tconst isInSelecting = editor.isIn('select.idle')\n\t\t\tif (isInSelecting) {\n\t\t\t\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\t\t\t\tif (selectedShapeIds !== rPrevSelectedShapeIds.current) {\n\t\t\t\t\trPrevSelectedShapeIds.current = selectedShapeIds\n\t\t\t\t\tunsafe__withoutCapture(() => {\n\t\t\t\t\t\tconst a11yLive = generateShapeAnnouncementMessage({\n\t\t\t\t\t\t\teditor,\n\t\t\t\t\t\t\tselectedShapeIds,\n\t\t\t\t\t\t\tmsg,\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tif (a11yLive) {\n\t\t\t\t\t\t\ta11y.announce({ msg: a11yLive })\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, a11y, msg]\n\t)\n}\n\nconst useA11yDebug = (msg: string | undefined) => {\n\tconst container = useContainer()\n\n\tuseEffect(() => {\n\t\tif (debugFlags.a11y.get()) {\n\t\t\tconst log = (msg: string) => {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.debug(\n\t\t\t\t\t`%ca11y%c: ${msg}`,\n\t\t\t\t\t`color: white; background: #40C057; padding: 2px;border-radius: 3px;`,\n\t\t\t\t\t'font-weight: normal'\n\t\t\t\t)\n\t\t\t}\n\t\t\tconst handleKeyUp = (e: KeyboardEvent) => {\n\t\t\t\tconst el = document.activeElement\n\t\t\t\tif (\n\t\t\t\t\te.key === 'Tab' &&\n\t\t\t\t\tel &&\n\t\t\t\t\tel !== document.body &&\n\t\t\t\t\t!el.classList.contains('tl-container')\n\t\t\t\t) {\n\t\t\t\t\tconst label = el.getAttribute('aria-label') || el.getAttribute('title') || el.textContent\n\t\t\t\t\tif (label) {\n\t\t\t\t\t\tlog(label)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (msg) {\n\t\t\t\tlog(msg)\n\t\t\t}\n\n\t\t\tdocument.addEventListener('keyup', handleKeyUp)\n\t\t\treturn () => document.removeEventListener('keyup', handleKeyUp)\n\t\t}\n\t}, [container, msg])\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["msg"]
7
7
  }
@@ -13,6 +13,7 @@ function LanguageMenu() {
13
13
  TldrawUiMenuCheckboxItem,
14
14
  {
15
15
  id: `language-${locale}`,
16
+ lang: locale,
16
17
  title: locale,
17
18
  label,
18
19
  checked: locale === currentLanguage,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/ui/components/LanguageMenu.tsx"],
4
- "sourcesContent": ["import { LANGUAGES, useMaybeEditor, useValue } from '@tldraw/editor'\nimport { useUiEvents } from '../context/events'\nimport { TldrawUiMenuCheckboxItem } from './primitives/menus/TldrawUiMenuCheckboxItem'\nimport { TldrawUiMenuGroup } from './primitives/menus/TldrawUiMenuGroup'\nimport { TldrawUiMenuSubmenu } from './primitives/menus/TldrawUiMenuSubmenu'\n\n/** @public @react */\nexport function LanguageMenu() {\n\tconst editor = useMaybeEditor()\n\tconst trackEvent = useUiEvents()\n\tconst currentLanguage = useValue('locale', () => editor?.user.getLocale(), [editor])\n\n\tif (!editor) return null\n\n\treturn (\n\t\t<TldrawUiMenuSubmenu id=\"help menu language\" label=\"menu.language\">\n\t\t\t<TldrawUiMenuGroup id=\"languages\" className=\"tlui-language-menu\">\n\t\t\t\t{LANGUAGES.map(({ locale, label }) => (\n\t\t\t\t\t<TldrawUiMenuCheckboxItem\n\t\t\t\t\t\tid={`language-${locale}`}\n\t\t\t\t\t\tkey={locale}\n\t\t\t\t\t\ttitle={locale}\n\t\t\t\t\t\tlabel={label}\n\t\t\t\t\t\tchecked={locale === currentLanguage}\n\t\t\t\t\t\treadonlyOk\n\t\t\t\t\t\tonSelect={() => {\n\t\t\t\t\t\t\teditor.user.updateUserPreferences({ locale })\n\t\t\t\t\t\t\ttrackEvent('change-language', { source: 'menu', locale })\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</TldrawUiMenuGroup>\n\t\t</TldrawUiMenuSubmenu>\n\t)\n}\n"],
5
- "mappings": "AAkBK;AAlBL,SAAS,WAAW,gBAAgB,gBAAgB;AACpD,SAAS,mBAAmB;AAC5B,SAAS,gCAAgC;AACzC,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AAG7B,SAAS,eAAe;AAC9B,QAAM,SAAS,eAAe;AAC9B,QAAM,aAAa,YAAY;AAC/B,QAAM,kBAAkB,SAAS,UAAU,MAAM,QAAQ,KAAK,UAAU,GAAG,CAAC,MAAM,CAAC;AAEnF,MAAI,CAAC,OAAQ,QAAO;AAEpB,SACC,oBAAC,uBAAoB,IAAG,sBAAqB,OAAM,iBAClD,8BAAC,qBAAkB,IAAG,aAAY,WAAU,sBAC1C,oBAAU,IAAI,CAAC,EAAE,QAAQ,MAAM,MAC/B;AAAA,IAAC;AAAA;AAAA,MACA,IAAI,YAAY,MAAM;AAAA,MAEtB,OAAO;AAAA,MACP;AAAA,MACA,SAAS,WAAW;AAAA,MACpB,YAAU;AAAA,MACV,UAAU,MAAM;AACf,eAAO,KAAK,sBAAsB,EAAE,OAAO,CAAC;AAC5C,mBAAW,mBAAmB,EAAE,QAAQ,QAAQ,OAAO,CAAC;AAAA,MACzD;AAAA;AAAA,IARK;AAAA,EASN,CACA,GACF,GACD;AAEF;",
4
+ "sourcesContent": ["import { LANGUAGES, useMaybeEditor, useValue } from '@tldraw/editor'\nimport { useUiEvents } from '../context/events'\nimport { TldrawUiMenuCheckboxItem } from './primitives/menus/TldrawUiMenuCheckboxItem'\nimport { TldrawUiMenuGroup } from './primitives/menus/TldrawUiMenuGroup'\nimport { TldrawUiMenuSubmenu } from './primitives/menus/TldrawUiMenuSubmenu'\n\n/** @public @react */\nexport function LanguageMenu() {\n\tconst editor = useMaybeEditor()\n\tconst trackEvent = useUiEvents()\n\tconst currentLanguage = useValue('locale', () => editor?.user.getLocale(), [editor])\n\n\tif (!editor) return null\n\n\treturn (\n\t\t<TldrawUiMenuSubmenu id=\"help menu language\" label=\"menu.language\">\n\t\t\t<TldrawUiMenuGroup id=\"languages\" className=\"tlui-language-menu\">\n\t\t\t\t{LANGUAGES.map(({ locale, label }) => (\n\t\t\t\t\t<TldrawUiMenuCheckboxItem\n\t\t\t\t\t\tid={`language-${locale}`}\n\t\t\t\t\t\tlang={locale}\n\t\t\t\t\t\tkey={locale}\n\t\t\t\t\t\ttitle={locale}\n\t\t\t\t\t\tlabel={label}\n\t\t\t\t\t\tchecked={locale === currentLanguage}\n\t\t\t\t\t\treadonlyOk\n\t\t\t\t\t\tonSelect={() => {\n\t\t\t\t\t\t\teditor.user.updateUserPreferences({ locale })\n\t\t\t\t\t\t\ttrackEvent('change-language', { source: 'menu', locale })\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</TldrawUiMenuGroup>\n\t\t</TldrawUiMenuSubmenu>\n\t)\n}\n"],
5
+ "mappings": "AAkBK;AAlBL,SAAS,WAAW,gBAAgB,gBAAgB;AACpD,SAAS,mBAAmB;AAC5B,SAAS,gCAAgC;AACzC,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AAG7B,SAAS,eAAe;AAC9B,QAAM,SAAS,eAAe;AAC9B,QAAM,aAAa,YAAY;AAC/B,QAAM,kBAAkB,SAAS,UAAU,MAAM,QAAQ,KAAK,UAAU,GAAG,CAAC,MAAM,CAAC;AAEnF,MAAI,CAAC,OAAQ,QAAO;AAEpB,SACC,oBAAC,uBAAoB,IAAG,sBAAqB,OAAM,iBAClD,8BAAC,qBAAkB,IAAG,aAAY,WAAU,sBAC1C,oBAAU,IAAI,CAAC,EAAE,QAAQ,MAAM,MAC/B;AAAA,IAAC;AAAA;AAAA,MACA,IAAI,YAAY,MAAM;AAAA,MACtB,MAAM;AAAA,MAEN,OAAO;AAAA,MACP;AAAA,MACA,SAAS,WAAW;AAAA,MACpB,YAAU;AAAA,MACV,UAAU,MAAM;AACf,eAAO,KAAK,sBAAsB,EAAE,OAAO,CAAC;AAC5C,mBAAW,mBAAmB,EAAE,QAAQ,QAAQ,OAAO,CAAC;AAAA,MACzD;AAAA;AAAA,IARK;AAAA,EASN,CACA,GACF,GACD;AAEF;",
6
6
  "names": []
7
7
  }
@@ -132,7 +132,7 @@ function DefaultMinimap() {
132
132
  type: "pointer",
133
133
  target: "canvas",
134
134
  name: "pointer_move",
135
- ...getPointerInfo(e),
135
+ ...getPointerInfo(editor, e),
136
136
  point: screenPoint,
137
137
  isPen: editor.getInstanceState().isPenMode
138
138
  };
@@ -169,6 +169,7 @@ function DefaultMinimap() {
169
169
  {
170
170
  role: "img",
171
171
  "aria-label": msg("navigation-zone.minimap"),
172
+ "data-testid": "minimap.canvas",
172
173
  ref: rCanvas,
173
174
  className: "tlui-minimap__canvas",
174
175
  onDoubleClick,