tldraw 3.16.0-next.4337ae1ab96d → 3.16.0-next.8eb6d5c2d8f4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +100 -14
- package/dist-cjs/index.js +6 -2
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/defaultExternalContentHandlers.js +10 -0
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/arrow-types.js.map +1 -1
- package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +3 -2
- package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +1 -1
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +4 -4
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +2 -1
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js +8 -2
- package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +1 -0
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +2 -1
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +4 -4
- package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +3 -3
- package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
- package/dist-cjs/lib/shapes/text/PlainTextArea.js +3 -2
- package/dist-cjs/lib/shapes/text/PlainTextArea.js.map +2 -2
- package/dist-cjs/lib/shapes/text/RichTextArea.js +3 -3
- package/dist-cjs/lib/shapes/text/RichTextArea.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +3 -1
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
- package/dist-cjs/lib/ui/components/A11y.js +1 -1
- package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
- package/dist-cjs/lib/ui/components/AccessibilityMenu.js +1 -1
- package/dist-cjs/lib/ui/components/AccessibilityMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/InputModeMenu.js +77 -0
- package/dist-cjs/lib/ui/components/InputModeMenu.js.map +7 -0
- package/dist-cjs/lib/ui/components/LanguageMenu.js +1 -0
- package/dist-cjs/lib/ui/components/LanguageMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js +2 -0
- package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +2 -1
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +1 -1
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +4 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +12 -3
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js +4 -2
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +3 -2
- package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +5 -4
- package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +1 -1
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +6 -2
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
- package/dist-cjs/lib/ui/components/menu-items.js +6 -4
- package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +5 -3
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +1 -0
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +68 -20
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js +3 -0
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +8 -8
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +11 -25
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/context/events.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +1 -1
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +11 -3
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-esm/index.d.mts +100 -14
- package/dist-esm/index.mjs +11 -3
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/defaultExternalContentHandlers.mjs +10 -0
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +3 -2
- package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +1 -1
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +4 -5
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +2 -1
- package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs +9 -3
- package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +1 -0
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +2 -1
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +5 -5
- package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +3 -4
- package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/PlainTextArea.mjs +4 -3
- package/dist-esm/lib/shapes/text/PlainTextArea.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/RichTextArea.mjs +3 -4
- package/dist-esm/lib/shapes/text/RichTextArea.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +3 -1
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
- package/dist-esm/lib/ui/components/A11y.mjs +1 -2
- package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
- package/dist-esm/lib/ui/components/AccessibilityMenu.mjs +3 -3
- package/dist-esm/lib/ui/components/AccessibilityMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/InputModeMenu.mjs +57 -0
- package/dist-esm/lib/ui/components/InputModeMenu.mjs.map +7 -0
- package/dist-esm/lib/ui/components/LanguageMenu.mjs +1 -0
- package/dist-esm/lib/ui/components/LanguageMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs +2 -0
- package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +2 -1
- package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +1 -2
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +4 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +12 -3
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs +4 -2
- package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +3 -2
- package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +5 -4
- package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +1 -1
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +6 -2
- package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
- package/dist-esm/lib/ui/components/menu-items.mjs +6 -4
- package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +1 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +6 -4
- package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +1 -1
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +1 -0
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +69 -20
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs +3 -0
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +8 -8
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +11 -25
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/context/events.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +1 -2
- package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +11 -3
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +8 -1
- package/src/lib/defaultExternalContentHandlers.ts +14 -0
- package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +83 -13
- package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +99 -5
- package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +41 -0
- package/src/lib/shapes/arrow/arrow-types.ts +3 -5
- package/src/lib/shapes/arrow/arrowTargetState.ts +34 -3
- package/src/lib/shapes/arrow/toolStates/Pointing.tsx +1 -1
- package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +4 -5
- package/src/lib/shapes/frame/FrameShapeUtil.tsx +1 -0
- package/src/lib/shapes/frame/components/FrameLabelInput.tsx +10 -3
- package/src/lib/shapes/geo/GeoShapeUtil.tsx +1 -0
- package/src/lib/shapes/note/NoteShapeUtil.tsx +1 -0
- package/src/lib/shapes/shared/HyperlinkButton.tsx +5 -5
- package/src/lib/shapes/shared/useEditablePlainText.ts +3 -4
- package/src/lib/shapes/text/PlainTextArea.tsx +4 -3
- package/src/lib/shapes/text/RichTextArea.tsx +3 -4
- package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +6 -2
- package/src/lib/ui/components/A11y.tsx +1 -2
- package/src/lib/ui/components/AccessibilityMenu.tsx +2 -2
- package/src/lib/ui/components/InputModeMenu.tsx +65 -0
- package/src/lib/ui/components/LanguageMenu.tsx +1 -0
- package/src/lib/ui/components/MainMenu/DefaultMainMenuContent.tsx +4 -0
- package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +2 -1
- package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +1 -2
- package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +4 -2
- package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +4 -2
- package/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx +10 -3
- package/src/lib/ui/components/StylePanel/StylePanelContext.tsx +5 -3
- package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +4 -3
- package/src/lib/ui/components/Toolbar/LinkEditor.tsx +6 -5
- package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +1 -1
- package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +9 -2
- package/src/lib/ui/components/menu-items.tsx +5 -3
- package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +1 -2
- package/src/lib/ui/components/primitives/TldrawUiInput.tsx +6 -3
- package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +2 -2
- package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +2 -1
- package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +65 -14
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +4 -0
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +9 -9
- package/src/lib/ui/context/actions.tsx +18 -27
- package/src/lib/ui/context/events.tsx +2 -1
- package/src/lib/ui/hooks/useClipboardEvents.ts +1 -2
- package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +10 -2
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +11 -3
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +25 -2
- package/src/test/TestEditor.ts +8 -2
- package/src/test/commands/setCamera.test.ts +13 -0
- package/src/test/frames.test.ts +15 -0
- package/src/test/getCulledShapes.test.tsx +71 -2
- package/tldraw.css +33 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { tlenv, tltime, useMaybeEditor } from "@tldraw/editor";
|
|
3
3
|
import classNames from "classnames";
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import { useTranslation } from "../../hooks/useTranslation/useTranslation.mjs";
|
|
@@ -24,7 +24,8 @@ const TldrawUiInput = React.forwardRef(
|
|
|
24
24
|
children,
|
|
25
25
|
value,
|
|
26
26
|
"data-testid": dataTestId,
|
|
27
|
-
disabled
|
|
27
|
+
disabled,
|
|
28
|
+
"aria-label": ariaLabel
|
|
28
29
|
}, ref) {
|
|
29
30
|
const editor = useMaybeEditor();
|
|
30
31
|
const rInputRef = React.useRef(null);
|
|
@@ -70,7 +71,7 @@ const TldrawUiInput = React.forwardRef(
|
|
|
70
71
|
case "Enter": {
|
|
71
72
|
if (isComposing.current) return;
|
|
72
73
|
e.currentTarget.blur();
|
|
73
|
-
|
|
74
|
+
e.stopPropagation();
|
|
74
75
|
onComplete?.(e.currentTarget.value);
|
|
75
76
|
break;
|
|
76
77
|
}
|
|
@@ -78,7 +79,7 @@ const TldrawUiInput = React.forwardRef(
|
|
|
78
79
|
e.currentTarget.value = rInitialValue.current;
|
|
79
80
|
onCancel?.(e.currentTarget.value);
|
|
80
81
|
e.currentTarget.blur();
|
|
81
|
-
|
|
82
|
+
e.stopPropagation();
|
|
82
83
|
break;
|
|
83
84
|
}
|
|
84
85
|
}
|
|
@@ -145,6 +146,7 @@ const TldrawUiInput = React.forwardRef(
|
|
|
145
146
|
onCompositionStart: handleCompositionStart,
|
|
146
147
|
onCompositionEnd: handleCompositionEnd,
|
|
147
148
|
autoFocus,
|
|
149
|
+
"aria-label": ariaLabel,
|
|
148
150
|
placeholder,
|
|
149
151
|
value,
|
|
150
152
|
"data-testid": dataTestId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/ui/components/primitives/TldrawUiInput.tsx"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { tlenv, tltime, useMaybeEditor } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport * as React from 'react'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TLUiIconType } from '../../icon-types'\nimport { TldrawUiIcon } from './TldrawUiIcon'\n\n/** @public */\nexport interface TLUiInputProps {\n\tdisabled?: boolean\n\tlabel?: TLUiTranslationKey | Exclude<string, TLUiTranslationKey>\n\ticon?: TLUiIconType | Exclude<string, TLUiIconType>\n\ticonLeft?: TLUiIconType | Exclude<string, TLUiIconType>\n\ticonLabel?: TLUiTranslationKey | Exclude<string, TLUiTranslationKey>\n\tautoFocus?: boolean\n\tautoSelect?: boolean\n\tchildren?: React.ReactNode\n\tdefaultValue?: string\n\tplaceholder?: string\n\tonComplete?(value: string): void\n\tonValueChange?(value: string): void\n\tonCancel?(value: string): void\n\tonBlur?(value: string): void\n\tonFocus?(): void\n\tclassName?: string\n\t/**\n\t * Usually on iOS when you focus an input, the browser will adjust the viewport to bring the input\n\t * into view. Sometimes this doesn't work properly though - for example, if the input is newly\n\t * created, iOS seems to have a hard time adjusting the viewport for it. This prop allows you to\n\t * opt-in to some extra code to manually bring the input into view when the visual viewport of the\n\t * browser changes, but we don't want to use it everywhere because generally the native behavior\n\t * looks nicer in scenarios where it's sufficient.\n\t */\n\tshouldManuallyMaintainScrollPositionWhenFocused?: boolean\n\tvalue?: string\n\t'data-testid'?: string\n\t'aria-label'?: string\n}\n\n/** @public @react */\nexport const TldrawUiInput = React.forwardRef<HTMLInputElement, TLUiInputProps>(\n\tfunction TldrawUiInput(\n\t\t{\n\t\t\tclassName,\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ticonLeft,\n\t\t\ticonLabel,\n\t\t\tautoSelect = false,\n\t\t\tautoFocus = false,\n\t\t\tdefaultValue,\n\t\t\tplaceholder,\n\t\t\tonComplete,\n\t\t\tonValueChange,\n\t\t\tonCancel,\n\t\t\tonFocus,\n\t\t\tonBlur,\n\t\t\tshouldManuallyMaintainScrollPositionWhenFocused = false,\n\t\t\tchildren,\n\t\t\tvalue,\n\t\t\t'data-testid': dataTestId,\n\t\t\tdisabled,\n\t\t\t'aria-label': ariaLabel,\n\t\t},\n\t\tref\n\t) {\n\t\tconst editor = useMaybeEditor()\n\t\tconst rInputRef = React.useRef<HTMLInputElement>(null)\n\n\t\t// combine rInputRef and ref\n\t\tReact.useImperativeHandle(ref, () => rInputRef.current as HTMLInputElement)\n\n\t\tconst msg = useTranslation()\n\t\tconst rInitialValue = React.useRef<string>(defaultValue ?? '')\n\t\tconst rCurrentValue = React.useRef<string>(defaultValue ?? '')\n\n\t\tconst isComposing = React.useRef(false)\n\n\t\tconst [isFocused, setIsFocused] = React.useState(false)\n\t\tconst handleFocus = React.useCallback(\n\t\t\t(e: React.FocusEvent<HTMLInputElement>) => {\n\t\t\t\tsetIsFocused(true)\n\t\t\t\tconst elm = e.currentTarget as HTMLInputElement\n\t\t\t\trCurrentValue.current = elm.value\n\t\t\t\tif (editor) {\n\t\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\t\tif (autoSelect) {\n\t\t\t\t\t\t\telm.select()\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\ttltime.requestAnimationFrame('anon', () => {\n\t\t\t\t\t\tif (autoSelect) {\n\t\t\t\t\t\t\telm.select()\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tonFocus?.()\n\t\t\t},\n\t\t\t[autoSelect, editor, onFocus]\n\t\t)\n\n\t\tconst handleChange = React.useCallback(\n\t\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\n\t\t\t\tconst value = e.currentTarget.value\n\t\t\t\trCurrentValue.current = value\n\t\t\t\tonValueChange?.(value)\n\t\t\t},\n\t\t\t[onValueChange]\n\t\t)\n\n\t\t// We use keydown capture, because we want to get the escape key event.\n\t\tconst handleKeyDownCapture = React.useCallback(\n\t\t\t(e: React.KeyboardEvent<HTMLInputElement>) => {\n\t\t\t\tswitch (e.key) {\n\t\t\t\t\tcase 'Enter': {\n\t\t\t\t\t\t// In Chrome, if the user presses the Enter key while using the IME and calls\n\t\t\t\t\t\t// `e.currentTarget.blur()` in the event callback here, it will trigger an\n\t\t\t\t\t\t// `onChange` with a duplicated text value.\n\t\t\t\t\t\tif (isComposing.current) return\n\t\t\t\t\t\te.currentTarget.blur()\n\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\tonComplete?.(e.currentTarget.value)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'Escape': {\n\t\t\t\t\t\te.currentTarget.value = rInitialValue.current\n\t\t\t\t\t\tonCancel?.(e.currentTarget.value)\n\t\t\t\t\t\te.currentTarget.blur()\n\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t[onComplete, onCancel]\n\t\t)\n\n\t\tconst handleBlur = React.useCallback(\n\t\t\t(e: React.FocusEvent<HTMLInputElement>) => {\n\t\t\t\tsetIsFocused(false)\n\t\t\t\tconst value = e.currentTarget.value\n\t\t\t\tonBlur?.(value)\n\t\t\t},\n\t\t\t[onBlur]\n\t\t)\n\n\t\tconst handleCompositionStart = React.useCallback(() => (isComposing.current = true), [])\n\t\tconst handleCompositionEnd = React.useCallback(() => (isComposing.current = false), [])\n\n\t\tReact.useEffect(() => {\n\t\t\tif (!tlenv.isIos) return\n\n\t\t\tconst visualViewport = window.visualViewport\n\t\t\tif (isFocused && shouldManuallyMaintainScrollPositionWhenFocused && visualViewport) {\n\t\t\t\tconst onViewportChange = () => {\n\t\t\t\t\trInputRef.current?.scrollIntoView({ block: 'center' })\n\t\t\t\t}\n\t\t\t\tvisualViewport.addEventListener('resize', onViewportChange)\n\t\t\t\tvisualViewport.addEventListener('scroll', onViewportChange)\n\n\t\t\t\tif (editor) {\n\t\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\t\trInputRef.current?.scrollIntoView({ block: 'center' })\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\ttltime.requestAnimationFrame('anon', () => {\n\t\t\t\t\t\trInputRef.current?.scrollIntoView({ block: 'center' })\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\treturn () => {\n\t\t\t\t\tvisualViewport.removeEventListener('resize', onViewportChange)\n\t\t\t\t\tvisualViewport.removeEventListener('scroll', onViewportChange)\n\t\t\t\t}\n\t\t\t}\n\t\t}, [isFocused, editor, shouldManuallyMaintainScrollPositionWhenFocused])\n\n\t\treturn (\n\t\t\t<div draggable={false} className=\"tlui-input__wrapper\">\n\t\t\t\t{children}\n\t\t\t\t{label && <label>{msg(label)}</label>}\n\t\t\t\t{iconLeft && (\n\t\t\t\t\t<TldrawUiIcon\n\t\t\t\t\t\tlabel={iconLabel ? msg(iconLabel) : ''}\n\t\t\t\t\t\ticon={iconLeft}\n\t\t\t\t\t\tclassName=\"tlui-icon-left\"\n\t\t\t\t\t\tsmall\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<input\n\t\t\t\t\tref={rInputRef}\n\t\t\t\t\tclassName={classNames('tlui-input', className)}\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tdefaultValue={defaultValue}\n\t\t\t\t\tonKeyDownCapture={handleKeyDownCapture}\n\t\t\t\t\tonChange={handleChange}\n\t\t\t\t\tonFocus={handleFocus}\n\t\t\t\t\tonBlur={handleBlur}\n\t\t\t\t\tonCompositionStart={handleCompositionStart}\n\t\t\t\t\tonCompositionEnd={handleCompositionEnd}\n\t\t\t\t\tautoFocus={autoFocus}\n\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\tvalue={value}\n\t\t\t\t\tdata-testid={dataTestId}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t/>\n\t\t\t\t{icon && (\n\t\t\t\t\t<TldrawUiIcon label={iconLabel ? msg(iconLabel) : ''} icon={icon} small={!!label} />\n\t\t\t\t)}\n\t\t\t</div>\n\t\t)\n\t}\n)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["TldrawUiInput", "value"]
|
|
7
7
|
}
|
|
@@ -29,7 +29,7 @@ const TldrawUiSlider = React.forwardRef(function Slider({
|
|
|
29
29
|
);
|
|
30
30
|
const handlePointerDown = useCallback(() => {
|
|
31
31
|
tooltipManager.hideAllTooltips();
|
|
32
|
-
onHistoryMark("click slider");
|
|
32
|
+
onHistoryMark?.("click slider");
|
|
33
33
|
}, [onHistoryMark]);
|
|
34
34
|
useEffect(() => {
|
|
35
35
|
const timeout = tltime.setTimeout(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/ui/components/primitives/TldrawUiSlider.tsx"],
|
|
4
|
-
"sourcesContent": ["import { tltime } from '@tldraw/editor'\nimport { Slider as _Slider } from 'radix-ui'\nimport React, { useCallback, useEffect, useState } from 'react'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiTooltip, tooltipManager } from './TldrawUiTooltip'\n\n/** @public */\nexport interface TLUiSliderProps {\n\tmin?: number\n\tsteps: number\n\tvalue: number | null\n\tlabel: string\n\ttitle: string\n\tonValueChange(value: number): void\n\tonHistoryMark(id: string): void\n\t'data-testid'?: string\n\tariaValueModifier?: number\n}\n\n/** @public @react */\nexport const TldrawUiSlider = React.forwardRef<HTMLDivElement, TLUiSliderProps>(function Slider(\n\t{\n\t\tonHistoryMark,\n\t\ttitle,\n\t\tmin,\n\t\tsteps,\n\t\tvalue,\n\t\tlabel,\n\t\tonValueChange,\n\t\t['data-testid']: testId,\n\t\tariaValueModifier = 1,\n\t}: TLUiSliderProps,\n\tref\n) {\n\tconst msg = useTranslation()\n\tconst [titleAndLabel, setTitleAndLabel] = useState('')\n\n\t// XXX: Radix starts out our slider with a tabIndex of 0\n\t// This causes some tab focusing issues, most prevelant in MobileStylePanel,\n\t// where it grabs the focus. This works around it.\n\tconst [tabIndex, setTabIndex] = useState(-1)\n\tuseEffect(() => {\n\t\tsetTabIndex(0)\n\t}, [])\n\n\tconst handleValueChange = useCallback(\n\t\t(value: number[]) => {\n\t\t\tonValueChange(value[0])\n\t\t},\n\t\t[onValueChange]\n\t)\n\n\tconst handlePointerDown = useCallback(() => {\n\t\ttooltipManager.hideAllTooltips()\n\t\tonHistoryMark('click slider')\n\t}, [onHistoryMark])\n\n\t// N.B. This is a bit silly. The Radix slider auto-focuses which\n\t// triggers TldrawUiTooltip handleFocus when we dbl-click to edit an image,\n\t// which in turn makes the tooltip display prematurely.\n\t// This makes it wait until we've focused to show the tooltip.\n\tuseEffect(() => {\n\t\tconst timeout = tltime.setTimeout(\n\t\t\t'set title and label',\n\t\t\t() => {\n\t\t\t\tsetTitleAndLabel(title + ' \u2014 ' + msg(label as TLUiTranslationKey))\n\t\t\t},\n\t\t\t0\n\t\t)\n\t\treturn () => clearTimeout(timeout)\n\t}, [label, msg, title])\n\n\t// N.B. Annoying. For a11y purposes, we need Tab to work.\n\t// For some reason, Radix has some custom behavior here\n\t// that interferes with tabbing past the slider and then\n\t// you get stuck in the slider.\n\tconst handleKeyEvent = useCallback((event: React.KeyboardEvent) => {\n\t\tif (event.key === 'Tab') {\n\t\t\tevent.stopPropagation()\n\t\t}\n\t}, [])\n\n\treturn (\n\t\t<div className=\"tlui-slider__container\">\n\t\t\t<TldrawUiTooltip content={titleAndLabel}>\n\t\t\t\t<_Slider.Root\n\t\t\t\t\tdata-testid={testId}\n\t\t\t\t\tclassName=\"tlui-slider\"\n\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\tmin={min ?? 0}\n\t\t\t\t\tmax={steps}\n\t\t\t\t\tstep={1}\n\t\t\t\t\tvalue={value !== null ? [value] : undefined}\n\t\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\t\tonValueChange={handleValueChange}\n\t\t\t\t\tonKeyDownCapture={handleKeyEvent}\n\t\t\t\t\tonKeyUpCapture={handleKeyEvent}\n\t\t\t\t>\n\t\t\t\t\t<_Slider.Track className=\"tlui-slider__track\" dir=\"ltr\">\n\t\t\t\t\t\t{value !== null && <_Slider.Range className=\"tlui-slider__range\" dir=\"ltr\" />}\n\t\t\t\t\t</_Slider.Track>\n\t\t\t\t\t{value !== null && (\n\t\t\t\t\t\t<_Slider.Thumb\n\t\t\t\t\t\t\taria-valuemin={(min ?? 0) * ariaValueModifier}\n\t\t\t\t\t\t\taria-valuenow={value * ariaValueModifier}\n\t\t\t\t\t\t\taria-valuemax={steps * ariaValueModifier}\n\t\t\t\t\t\t\taria-label={titleAndLabel}\n\t\t\t\t\t\t\tclassName=\"tlui-slider__thumb\"\n\t\t\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\t\ttabIndex={tabIndex}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</_Slider.Root>\n\t\t\t</TldrawUiTooltip>\n\t\t</div>\n\t)\n})\n"],
|
|
5
|
-
"mappings": "AAsFI,SAcqB,KAdrB;AAtFJ,SAAS,cAAc;AACvB,SAAS,UAAU,eAAe;AAClC,OAAO,SAAS,aAAa,WAAW,gBAAgB;AAExD,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB,sBAAsB;AAgBzC,MAAM,iBAAiB,MAAM,WAA4C,SAAS,OACxF;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,CAAC,aAAa,GAAG;AAAA,EACjB,oBAAoB;AACrB,GACA,KACC;AACD,QAAM,MAAM,eAAe;AAC3B,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,EAAE;AAKrD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,EAAE;AAC3C,YAAU,MAAM;AACf,gBAAY,CAAC;AAAA,EACd,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAoB;AAAA,IACzB,CAACA,WAAoB;AACpB,oBAAcA,OAAM,CAAC,CAAC;AAAA,IACvB;AAAA,IACA,CAAC,aAAa;AAAA,EACf;AAEA,QAAM,oBAAoB,YAAY,MAAM;AAC3C,mBAAe,gBAAgB;AAC/B,
|
|
4
|
+
"sourcesContent": ["import { tltime } from '@tldraw/editor'\nimport { Slider as _Slider } from 'radix-ui'\nimport React, { useCallback, useEffect, useState } from 'react'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiTooltip, tooltipManager } from './TldrawUiTooltip'\n\n/** @public */\nexport interface TLUiSliderProps {\n\tmin?: number\n\tsteps: number\n\tvalue: number | null\n\tlabel: string\n\ttitle: string\n\tonValueChange(value: number): void\n\tonHistoryMark?(id: string): void\n\t'data-testid'?: string\n\tariaValueModifier?: number\n}\n\n/** @public @react */\nexport const TldrawUiSlider = React.forwardRef<HTMLDivElement, TLUiSliderProps>(function Slider(\n\t{\n\t\tonHistoryMark,\n\t\ttitle,\n\t\tmin,\n\t\tsteps,\n\t\tvalue,\n\t\tlabel,\n\t\tonValueChange,\n\t\t['data-testid']: testId,\n\t\tariaValueModifier = 1,\n\t}: TLUiSliderProps,\n\tref\n) {\n\tconst msg = useTranslation()\n\tconst [titleAndLabel, setTitleAndLabel] = useState('')\n\n\t// XXX: Radix starts out our slider with a tabIndex of 0\n\t// This causes some tab focusing issues, most prevelant in MobileStylePanel,\n\t// where it grabs the focus. This works around it.\n\tconst [tabIndex, setTabIndex] = useState(-1)\n\tuseEffect(() => {\n\t\tsetTabIndex(0)\n\t}, [])\n\n\tconst handleValueChange = useCallback(\n\t\t(value: number[]) => {\n\t\t\tonValueChange(value[0])\n\t\t},\n\t\t[onValueChange]\n\t)\n\n\tconst handlePointerDown = useCallback(() => {\n\t\ttooltipManager.hideAllTooltips()\n\t\tonHistoryMark?.('click slider')\n\t}, [onHistoryMark])\n\n\t// N.B. This is a bit silly. The Radix slider auto-focuses which\n\t// triggers TldrawUiTooltip handleFocus when we dbl-click to edit an image,\n\t// which in turn makes the tooltip display prematurely.\n\t// This makes it wait until we've focused to show the tooltip.\n\tuseEffect(() => {\n\t\tconst timeout = tltime.setTimeout(\n\t\t\t'set title and label',\n\t\t\t() => {\n\t\t\t\tsetTitleAndLabel(title + ' \u2014 ' + msg(label as TLUiTranslationKey))\n\t\t\t},\n\t\t\t0\n\t\t)\n\t\treturn () => clearTimeout(timeout)\n\t}, [label, msg, title])\n\n\t// N.B. Annoying. For a11y purposes, we need Tab to work.\n\t// For some reason, Radix has some custom behavior here\n\t// that interferes with tabbing past the slider and then\n\t// you get stuck in the slider.\n\tconst handleKeyEvent = useCallback((event: React.KeyboardEvent) => {\n\t\tif (event.key === 'Tab') {\n\t\t\tevent.stopPropagation()\n\t\t}\n\t}, [])\n\n\treturn (\n\t\t<div className=\"tlui-slider__container\">\n\t\t\t<TldrawUiTooltip content={titleAndLabel}>\n\t\t\t\t<_Slider.Root\n\t\t\t\t\tdata-testid={testId}\n\t\t\t\t\tclassName=\"tlui-slider\"\n\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\tmin={min ?? 0}\n\t\t\t\t\tmax={steps}\n\t\t\t\t\tstep={1}\n\t\t\t\t\tvalue={value !== null ? [value] : undefined}\n\t\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\t\tonValueChange={handleValueChange}\n\t\t\t\t\tonKeyDownCapture={handleKeyEvent}\n\t\t\t\t\tonKeyUpCapture={handleKeyEvent}\n\t\t\t\t>\n\t\t\t\t\t<_Slider.Track className=\"tlui-slider__track\" dir=\"ltr\">\n\t\t\t\t\t\t{value !== null && <_Slider.Range className=\"tlui-slider__range\" dir=\"ltr\" />}\n\t\t\t\t\t</_Slider.Track>\n\t\t\t\t\t{value !== null && (\n\t\t\t\t\t\t<_Slider.Thumb\n\t\t\t\t\t\t\taria-valuemin={(min ?? 0) * ariaValueModifier}\n\t\t\t\t\t\t\taria-valuenow={value * ariaValueModifier}\n\t\t\t\t\t\t\taria-valuemax={steps * ariaValueModifier}\n\t\t\t\t\t\t\taria-label={titleAndLabel}\n\t\t\t\t\t\t\tclassName=\"tlui-slider__thumb\"\n\t\t\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\t\ttabIndex={tabIndex}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</_Slider.Root>\n\t\t\t</TldrawUiTooltip>\n\t\t</div>\n\t)\n})\n"],
|
|
5
|
+
"mappings": "AAsFI,SAcqB,KAdrB;AAtFJ,SAAS,cAAc;AACvB,SAAS,UAAU,eAAe;AAClC,OAAO,SAAS,aAAa,WAAW,gBAAgB;AAExD,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB,sBAAsB;AAgBzC,MAAM,iBAAiB,MAAM,WAA4C,SAAS,OACxF;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,CAAC,aAAa,GAAG;AAAA,EACjB,oBAAoB;AACrB,GACA,KACC;AACD,QAAM,MAAM,eAAe;AAC3B,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,EAAE;AAKrD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,EAAE;AAC3C,YAAU,MAAM;AACf,gBAAY,CAAC;AAAA,EACd,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAoB;AAAA,IACzB,CAACA,WAAoB;AACpB,oBAAcA,OAAM,CAAC,CAAC;AAAA,IACvB;AAAA,IACA,CAAC,aAAa;AAAA,EACf;AAEA,QAAM,oBAAoB,YAAY,MAAM;AAC3C,mBAAe,gBAAgB;AAC/B,oBAAgB,cAAc;AAAA,EAC/B,GAAG,CAAC,aAAa,CAAC;AAMlB,YAAU,MAAM;AACf,UAAM,UAAU,OAAO;AAAA,MACtB;AAAA,MACA,MAAM;AACL,yBAAiB,QAAQ,aAAQ,IAAI,KAA2B,CAAC;AAAA,MAClE;AAAA,MACA;AAAA,IACD;AACA,WAAO,MAAM,aAAa,OAAO;AAAA,EAClC,GAAG,CAAC,OAAO,KAAK,KAAK,CAAC;AAMtB,QAAM,iBAAiB,YAAY,CAAC,UAA+B;AAClE,QAAI,MAAM,QAAQ,OAAO;AACxB,YAAM,gBAAgB;AAAA,IACvB;AAAA,EACD,GAAG,CAAC,CAAC;AAEL,SACC,oBAAC,SAAI,WAAU,0BACd,8BAAC,mBAAgB,SAAS,eACzB;AAAA,IAAC,QAAQ;AAAA,IAAR;AAAA,MACA,eAAa;AAAA,MACb,WAAU;AAAA,MACV,KAAI;AAAA,MACJ,KAAK,OAAO;AAAA,MACZ,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO,UAAU,OAAO,CAAC,KAAK,IAAI;AAAA,MAClC,eAAe;AAAA,MACf,eAAe;AAAA,MACf,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAEhB;AAAA,4BAAC,QAAQ,OAAR,EAAc,WAAU,sBAAqB,KAAI,OAChD,oBAAU,QAAQ,oBAAC,QAAQ,OAAR,EAAc,WAAU,sBAAqB,KAAI,OAAM,GAC5E;AAAA,QACC,UAAU,QACV;AAAA,UAAC,QAAQ;AAAA,UAAR;AAAA,YACA,kBAAgB,OAAO,KAAK;AAAA,YAC5B,iBAAe,QAAQ;AAAA,YACvB,iBAAe,QAAQ;AAAA,YACvB,cAAY;AAAA,YACZ,WAAU;AAAA,YACV,KAAI;AAAA,YACJ;AAAA,YACA;AAAA;AAAA,QACD;AAAA;AAAA;AAAA,EAEF,GACD,GACD;AAEF,CAAC;",
|
|
6
6
|
"names": ["value"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/ui/components/primitives/TldrawUiToolbar.tsx"],
|
|
4
|
-
"sourcesContent": ["import classnames from 'classnames'\nimport { Toolbar as _Toolbar } from 'radix-ui'\nimport React from 'react'\nimport { TldrawUiColumn, TldrawUiGrid, TldrawUiRow } from './layout'\nimport { TldrawUiTooltip } from './TldrawUiTooltip'\n\n/** @public */\nexport interface TLUiToolbarProps extends React.HTMLAttributes<HTMLDivElement> {\n\tchildren?: React.ReactNode\n\tclassName?: string\n\tdir?: 'ltr' | 'rtl'\n\tlabel: string\n\torientation?: 'horizontal' | 'vertical' | 'grid'\n\ttooltipSide?: 'top' | 'right' | 'bottom' | 'left'\n}\n\nconst LayoutByOrientation = {\n\thorizontal: TldrawUiRow,\n\tvertical: TldrawUiColumn,\n\tgrid: TldrawUiGrid,\n}\n\n/** @public @react */\nexport const TldrawUiToolbar = React.forwardRef<HTMLDivElement, TLUiToolbarProps>(\n\t(\n\t\t{\n\t\t\tchildren,\n\t\t\tclassName,\n\t\t\tlabel,\n\t\t\torientation = 'horizontal',\n\t\t\ttooltipSide,\n\t\t\t...props\n\t\t}: TLUiToolbarProps,\n\t\tref\n\t) => {\n\t\tconst Layout = LayoutByOrientation[orientation]\n\t\treturn (\n\t\t\t<Layout asChild tooltipSide={tooltipSide}>\n\t\t\t\t<_Toolbar.Root\n\t\t\t\t\tref={ref}\n\t\t\t\t\t{...props}\n\t\t\t\t\tclassName={classnames('tlui-toolbar', className)}\n\t\t\t\t\taria-label={label}\n\t\t\t\t\torientation={orientation === 'grid' ? 'horizontal' : orientation}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</_Toolbar.Root>\n\t\t\t</Layout>\n\t\t)\n\t}\n)\n\n/** @public */\nexport interface TLUiToolbarButtonProps extends React.HTMLAttributes<HTMLButtonElement> {\n\tasChild?: boolean\n\tchildren?: React.ReactNode\n\tclassName?: string\n\tdisabled?: boolean\n\tisActive?: boolean\n\ttype: 'icon' | 'tool' | 'menu'\n\ttooltip?: string\n}\n\n/** @public @react */\nexport const TldrawUiToolbarButton = React.forwardRef<HTMLButtonElement, TLUiToolbarButtonProps>(\n\t({ asChild, children, type, isActive, tooltip, ...props }: TLUiToolbarButtonProps, ref) => {\n\t\tconst button = (\n\t\t\t<_Toolbar.Button\n\t\t\t\tref={ref}\n\t\t\t\tasChild={asChild}\n\t\t\t\tdraggable={false}\n\t\t\t\tdata-isactive={isActive}\n\t\t\t\t{...props}\n\t\t\t\t// The tooltip takes care of this.\n\t\t\t\ttitle={undefined}\n\t\t\t\tclassName={classnames('tlui-button', `tlui-button__${type}`, props.className)}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</_Toolbar.Button>\n\t\t)\n\n\t\tconst tooltipContent = tooltip || props.title\n\n\t\treturn <TldrawUiTooltip content={tooltipContent}>{button}</TldrawUiTooltip>\n\t}\n)\n\n/** @public */\nexport interface TLUiToolbarToggleGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n\tchildren?: React.ReactNode\n\tclassName?: string\n\tdir?: 'ltr' | 'rtl'\n\tvalue: any\n\t// TODO: fix up this type later\n\tdefaultValue?: any\n\ttype: 'single' | 'multiple'\n\tasChild?: boolean\n}\n\n/** @public @react */\nexport const TldrawUiToolbarToggleGroup = ({\n\tchildren,\n\tclassName,\n\ttype,\n\tasChild,\n\t...props\n}: TLUiToolbarToggleGroupProps) => {\n\treturn (\n\t\t<_Toolbar.ToggleGroup\n\t\t\tasChild={asChild}\n\t\t\ttype={type}\n\t\t\t{...props}\n\t\t\t// TODO: this fixes a bug in Radix until they fix it.\n\t\t\t// https://github.com/radix-ui/primitives/issues/3188\n\t\t\t// https://github.com/radix-ui/primitives/pull/3189\n\t\t\trole=\"radiogroup\"\n\t\t\tclassName={classnames('tlui-toolbar-toggle-group', className)}\n\t\t>\n\t\t\t{children}\n\t\t</_Toolbar.ToggleGroup>\n\t)\n}\n\n/** @public */\nexport interface TLUiToolbarToggleItemProps extends React.HTMLAttributes<HTMLButtonElement> {\n\tchildren?: React.ReactNode\n\tclassName?: string\n\ttype: 'icon' | 'tool'\n\tvalue: string\n\ttooltip?:
|
|
5
|
-
"mappings": "AAsCI;AAtCJ,OAAO,gBAAgB;AACvB,SAAS,WAAW,gBAAgB;AACpC,OAAO,WAAW;AAClB,SAAS,gBAAgB,cAAc,mBAAmB;AAC1D,SAAS,uBAAuB;AAYhC,MAAM,sBAAsB;AAAA,EAC3B,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,MAAM;AACP;AAGO,MAAM,kBAAkB,MAAM;AAAA,EACpC,CACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA,GAAG;AAAA,EACJ,GACA,QACI;AACJ,UAAM,SAAS,oBAAoB,WAAW;AAC9C,WACC,oBAAC,UAAO,SAAO,MAAC,aACf;AAAA,MAAC,SAAS;AAAA,MAAT;AAAA,QACA;AAAA,QACC,GAAG;AAAA,QACJ,WAAW,WAAW,gBAAgB,SAAS;AAAA,QAC/C,cAAY;AAAA,QACZ,aAAa,gBAAgB,SAAS,eAAe;AAAA,QAEpD;AAAA;AAAA,IACF,GACD;AAAA,EAEF;AACD;AAcO,MAAM,wBAAwB,MAAM;AAAA,EAC1C,CAAC,EAAE,SAAS,UAAU,MAAM,UAAU,SAAS,GAAG,MAAM,GAA2B,QAAQ;AAC1F,UAAM,SACL;AAAA,MAAC,SAAS;AAAA,MAAT;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,iBAAe;AAAA,QACd,GAAG;AAAA,
|
|
4
|
+
"sourcesContent": ["import classnames from 'classnames'\nimport { Toolbar as _Toolbar } from 'radix-ui'\nimport React from 'react'\nimport { TldrawUiColumn, TldrawUiGrid, TldrawUiRow } from './layout'\nimport { TldrawUiTooltip } from './TldrawUiTooltip'\n\n/** @public */\nexport interface TLUiToolbarProps extends React.HTMLAttributes<HTMLDivElement> {\n\tchildren?: React.ReactNode\n\tclassName?: string\n\tdir?: 'ltr' | 'rtl'\n\tlabel: string\n\torientation?: 'horizontal' | 'vertical' | 'grid'\n\ttooltipSide?: 'top' | 'right' | 'bottom' | 'left'\n}\n\nconst LayoutByOrientation = {\n\thorizontal: TldrawUiRow,\n\tvertical: TldrawUiColumn,\n\tgrid: TldrawUiGrid,\n}\n\n/** @public @react */\nexport const TldrawUiToolbar = React.forwardRef<HTMLDivElement, TLUiToolbarProps>(\n\t(\n\t\t{\n\t\t\tchildren,\n\t\t\tclassName,\n\t\t\tlabel,\n\t\t\torientation = 'horizontal',\n\t\t\ttooltipSide,\n\t\t\t...props\n\t\t}: TLUiToolbarProps,\n\t\tref\n\t) => {\n\t\tconst Layout = LayoutByOrientation[orientation]\n\t\treturn (\n\t\t\t<Layout asChild tooltipSide={tooltipSide}>\n\t\t\t\t<_Toolbar.Root\n\t\t\t\t\tref={ref}\n\t\t\t\t\t{...props}\n\t\t\t\t\tclassName={classnames('tlui-toolbar', className)}\n\t\t\t\t\taria-label={label}\n\t\t\t\t\torientation={orientation === 'grid' ? 'horizontal' : orientation}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</_Toolbar.Root>\n\t\t\t</Layout>\n\t\t)\n\t}\n)\n\n/** @public */\nexport interface TLUiToolbarButtonProps extends React.HTMLAttributes<HTMLButtonElement> {\n\tasChild?: boolean\n\tchildren?: React.ReactNode\n\tclassName?: string\n\tdisabled?: boolean\n\tisActive?: boolean\n\ttype: 'icon' | 'tool' | 'menu'\n\ttooltip?: string\n}\n\n/** @public @react */\nexport const TldrawUiToolbarButton = React.forwardRef<HTMLButtonElement, TLUiToolbarButtonProps>(\n\t({ asChild, children, type, isActive, tooltip, ...props }: TLUiToolbarButtonProps, ref) => {\n\t\tconst button = (\n\t\t\t<_Toolbar.Button\n\t\t\t\tref={ref}\n\t\t\t\tasChild={asChild}\n\t\t\t\tdraggable={false}\n\t\t\t\tdata-isactive={isActive}\n\t\t\t\t{...props}\n\t\t\t\taria-label={props.title}\n\t\t\t\t// The tooltip takes care of this.\n\t\t\t\ttitle={undefined}\n\t\t\t\tclassName={classnames('tlui-button', `tlui-button__${type}`, props.className)}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</_Toolbar.Button>\n\t\t)\n\n\t\tconst tooltipContent = tooltip || props.title\n\n\t\treturn <TldrawUiTooltip content={tooltipContent}>{button}</TldrawUiTooltip>\n\t}\n)\n\n/** @public */\nexport interface TLUiToolbarToggleGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n\tchildren?: React.ReactNode\n\tclassName?: string\n\tdir?: 'ltr' | 'rtl'\n\tvalue: any\n\t// TODO: fix up this type later\n\tdefaultValue?: any\n\ttype: 'single' | 'multiple'\n\tasChild?: boolean\n}\n\n/** @public @react */\nexport const TldrawUiToolbarToggleGroup = ({\n\tchildren,\n\tclassName,\n\ttype,\n\tasChild,\n\t...props\n}: TLUiToolbarToggleGroupProps) => {\n\treturn (\n\t\t<_Toolbar.ToggleGroup\n\t\t\tasChild={asChild}\n\t\t\ttype={type}\n\t\t\t{...props}\n\t\t\t// TODO: this fixes a bug in Radix until they fix it.\n\t\t\t// https://github.com/radix-ui/primitives/issues/3188\n\t\t\t// https://github.com/radix-ui/primitives/pull/3189\n\t\t\trole=\"radiogroup\"\n\t\t\tclassName={classnames('tlui-toolbar-toggle-group', className)}\n\t\t>\n\t\t\t{children}\n\t\t</_Toolbar.ToggleGroup>\n\t)\n}\n\n/** @public */\nexport interface TLUiToolbarToggleItemProps extends React.HTMLAttributes<HTMLButtonElement> {\n\tchildren?: React.ReactNode\n\tclassName?: string\n\ttype: 'icon' | 'tool'\n\tvalue: string\n\ttooltip?: React.ReactNode\n}\n\n/** @public @react */\nexport const TldrawUiToolbarToggleItem = ({\n\tchildren,\n\tclassName,\n\ttype,\n\tvalue,\n\ttooltip,\n\t...props\n}: TLUiToolbarToggleItemProps) => {\n\tconst toggleItem = (\n\t\t<_Toolbar.ToggleItem\n\t\t\t{...props}\n\t\t\t// The tooltip takes care of this.\n\t\t\ttitle={undefined}\n\t\t\tclassName={classnames(\n\t\t\t\t'tlui-button',\n\t\t\t\t`tlui-button__${type}`,\n\t\t\t\t'tlui-toolbar-toggle-group-item',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tvalue={value}\n\t\t>\n\t\t\t{children}\n\t\t</_Toolbar.ToggleItem>\n\t)\n\n\tconst tooltipContent = tooltip || props.title\n\n\treturn <TldrawUiTooltip content={tooltipContent}>{toggleItem}</TldrawUiTooltip>\n}\n"],
|
|
5
|
+
"mappings": "AAsCI;AAtCJ,OAAO,gBAAgB;AACvB,SAAS,WAAW,gBAAgB;AACpC,OAAO,WAAW;AAClB,SAAS,gBAAgB,cAAc,mBAAmB;AAC1D,SAAS,uBAAuB;AAYhC,MAAM,sBAAsB;AAAA,EAC3B,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,MAAM;AACP;AAGO,MAAM,kBAAkB,MAAM;AAAA,EACpC,CACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA,GAAG;AAAA,EACJ,GACA,QACI;AACJ,UAAM,SAAS,oBAAoB,WAAW;AAC9C,WACC,oBAAC,UAAO,SAAO,MAAC,aACf;AAAA,MAAC,SAAS;AAAA,MAAT;AAAA,QACA;AAAA,QACC,GAAG;AAAA,QACJ,WAAW,WAAW,gBAAgB,SAAS;AAAA,QAC/C,cAAY;AAAA,QACZ,aAAa,gBAAgB,SAAS,eAAe;AAAA,QAEpD;AAAA;AAAA,IACF,GACD;AAAA,EAEF;AACD;AAcO,MAAM,wBAAwB,MAAM;AAAA,EAC1C,CAAC,EAAE,SAAS,UAAU,MAAM,UAAU,SAAS,GAAG,MAAM,GAA2B,QAAQ;AAC1F,UAAM,SACL;AAAA,MAAC,SAAS;AAAA,MAAT;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,iBAAe;AAAA,QACd,GAAG;AAAA,QACJ,cAAY,MAAM;AAAA,QAElB,OAAO;AAAA,QACP,WAAW,WAAW,eAAe,gBAAgB,IAAI,IAAI,MAAM,SAAS;AAAA,QAE3E;AAAA;AAAA,IACF;AAGD,UAAM,iBAAiB,WAAW,MAAM;AAExC,WAAO,oBAAC,mBAAgB,SAAS,gBAAiB,kBAAO;AAAA,EAC1D;AACD;AAeO,MAAM,6BAA6B,CAAC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACJ,MAAmC;AAClC,SACC;AAAA,IAAC,SAAS;AAAA,IAAT;AAAA,MACA;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAIJ,MAAK;AAAA,MACL,WAAW,WAAW,6BAA6B,SAAS;AAAA,MAE3D;AAAA;AAAA,EACF;AAEF;AAYO,MAAM,4BAA4B,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACJ,MAAkC;AACjC,QAAM,aACL;AAAA,IAAC,SAAS;AAAA,IAAT;AAAA,MACC,GAAG;AAAA,MAEJ,OAAO;AAAA,MACP,WAAW;AAAA,QACV;AAAA,QACA,gBAAgB,IAAI;AAAA,QACpB;AAAA,QACA;AAAA,MACD;AAAA,MACA;AAAA,MAEC;AAAA;AAAA,EACF;AAGD,QAAM,iBAAiB,WAAW,MAAM;AAExC,SAAO,oBAAC,mBAAgB,SAAS,gBAAiB,sBAAW;AAC9D;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -6,6 +6,7 @@ import React, {
|
|
|
6
6
|
forwardRef,
|
|
7
7
|
useContext,
|
|
8
8
|
useEffect,
|
|
9
|
+
useLayoutEffect,
|
|
9
10
|
useRef,
|
|
10
11
|
useState
|
|
11
12
|
} from "react";
|
|
@@ -36,6 +37,14 @@ class TooltipManager {
|
|
|
36
37
|
delayDuration
|
|
37
38
|
});
|
|
38
39
|
}
|
|
40
|
+
updateCurrentTooltip(tooltipId, update) {
|
|
41
|
+
this.currentTooltip.update((tooltip) => {
|
|
42
|
+
if (tooltip?.id === tooltipId) {
|
|
43
|
+
return update(tooltip);
|
|
44
|
+
}
|
|
45
|
+
return tooltip;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
39
48
|
hideTooltip(editor, tooltipId, instant = false) {
|
|
40
49
|
const hide = () => {
|
|
41
50
|
if (this.currentTooltip.get()?.id === tooltipId) {
|
|
@@ -96,6 +105,18 @@ function TooltipSingleton() {
|
|
|
96
105
|
tooltipManager.hideTooltip(editor, currentTooltip.id, true);
|
|
97
106
|
}
|
|
98
107
|
}, [cameraState, isOpen, currentTooltip, editor]);
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
function handleKeyDown(event) {
|
|
110
|
+
if (event.key === "Escape" && currentTooltip && isOpen) {
|
|
111
|
+
tooltipManager.hideTooltip(editor, currentTooltip.id);
|
|
112
|
+
event.stopPropagation();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
document.addEventListener("keydown", handleKeyDown, { capture: true });
|
|
116
|
+
return () => {
|
|
117
|
+
document.removeEventListener("keydown", handleKeyDown, { capture: true });
|
|
118
|
+
};
|
|
119
|
+
}, [editor, currentTooltip, isOpen]);
|
|
99
120
|
useEffect(() => {
|
|
100
121
|
let timer = null;
|
|
101
122
|
if (currentTooltip && triggerRef.current) {
|
|
@@ -161,6 +182,11 @@ const TldrawUiTooltip = forwardRef(
|
|
|
161
182
|
const editor = useMaybeEditor();
|
|
162
183
|
const tooltipId = useRef(uniqueId());
|
|
163
184
|
const hasProvider = useContext(TooltipSingletonContext);
|
|
185
|
+
const enhancedA11yMode = useValue(
|
|
186
|
+
"enhancedA11yMode",
|
|
187
|
+
() => editor?.user.getEnhancedA11yMode(),
|
|
188
|
+
[editor]
|
|
189
|
+
);
|
|
164
190
|
const orientationCtx = useTldrawUiOrientation();
|
|
165
191
|
const sideToUse = side ?? orientationCtx.tooltipSide;
|
|
166
192
|
useEffect(() => {
|
|
@@ -171,29 +197,52 @@ const TldrawUiTooltip = forwardRef(
|
|
|
171
197
|
}
|
|
172
198
|
};
|
|
173
199
|
}, [editor, hasProvider]);
|
|
200
|
+
useLayoutEffect(() => {
|
|
201
|
+
if (hasProvider && tooltipManager.getCurrentTooltipData()?.id === tooltipId.current) {
|
|
202
|
+
tooltipManager.updateCurrentTooltip(tooltipId.current, (tooltip) => ({
|
|
203
|
+
...tooltip,
|
|
204
|
+
content,
|
|
205
|
+
side: sideToUse,
|
|
206
|
+
sideOffset,
|
|
207
|
+
showOnMobile
|
|
208
|
+
}));
|
|
209
|
+
}
|
|
210
|
+
}, [content, sideToUse, sideOffset, showOnMobile, hasProvider]);
|
|
174
211
|
if (disabled || !content) {
|
|
175
212
|
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
176
213
|
}
|
|
177
|
-
|
|
178
|
-
if (
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
214
|
+
let delayDurationToUse;
|
|
215
|
+
if (enhancedA11yMode) {
|
|
216
|
+
delayDurationToUse = 0;
|
|
217
|
+
} else {
|
|
218
|
+
delayDurationToUse = delayDuration ?? (editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS);
|
|
219
|
+
}
|
|
220
|
+
if (!hasProvider || enhancedA11yMode) {
|
|
221
|
+
return /* @__PURE__ */ jsxs(
|
|
222
|
+
_Tooltip.Root,
|
|
223
|
+
{
|
|
224
|
+
delayDuration: delayDurationToUse,
|
|
225
|
+
disableHoverableContent: !enhancedA11yMode,
|
|
226
|
+
children: [
|
|
227
|
+
/* @__PURE__ */ jsx(_Tooltip.Trigger, { asChild: true, ref, children }),
|
|
228
|
+
/* @__PURE__ */ jsxs(
|
|
229
|
+
_Tooltip.Content,
|
|
230
|
+
{
|
|
231
|
+
className: "tlui-tooltip",
|
|
232
|
+
side: sideToUse,
|
|
233
|
+
sideOffset,
|
|
234
|
+
avoidCollisions: true,
|
|
235
|
+
collisionPadding: 8,
|
|
236
|
+
dir: "ltr",
|
|
237
|
+
children: [
|
|
238
|
+
content,
|
|
239
|
+
/* @__PURE__ */ jsx(_Tooltip.Arrow, { className: "tlui-tooltip__arrow" })
|
|
240
|
+
]
|
|
241
|
+
}
|
|
242
|
+
)
|
|
243
|
+
]
|
|
244
|
+
}
|
|
245
|
+
);
|
|
197
246
|
}
|
|
198
247
|
const child = React.Children.only(children);
|
|
199
248
|
assert(React.isValidElement(child), "TldrawUiTooltip children must be a single element");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/ui/components/primitives/TldrawUiTooltip.tsx"],
|
|
4
|
-
"sourcesContent": ["import { assert, Atom, atom, Editor, uniqueId, useMaybeEditor, useValue } from '@tldraw/editor'\nimport { Tooltip as _Tooltip } from 'radix-ui'\nimport React, {\n\tcreateContext,\n\tforwardRef,\n\tReactNode,\n\tuseContext,\n\tuseEffect,\n\tuseRef,\n\tuseState,\n} from 'react'\nimport { useTldrawUiOrientation } from './layout'\n\nconst DEFAULT_TOOLTIP_DELAY_MS = 700\n\n/** @public */\nexport interface TldrawUiTooltipProps {\n\tchildren: React.ReactNode\n\tcontent?: string | React.ReactNode\n\tside?: 'top' | 'right' | 'bottom' | 'left'\n\tsideOffset?: number\n\tdisabled?: boolean\n\tshowOnMobile?: boolean\n\tdelayDuration?: number\n}\n\n// Singleton tooltip manager\nclass TooltipManager {\n\tprivate static instance: TooltipManager | null = null\n\tprivate currentTooltip = atom<{\n\t\tid: string\n\t\tcontent: ReactNode\n\t\tside: 'top' | 'right' | 'bottom' | 'left'\n\t\tsideOffset: number\n\t\tshowOnMobile: boolean\n\t\ttargetElement: HTMLElement\n\t\tdelayDuration: number\n\t} | null>('current tooltip', null)\n\tprivate destroyTimeoutId: number | null = null\n\n\tstatic getInstance(): TooltipManager {\n\t\tif (!TooltipManager.instance) {\n\t\t\tTooltipManager.instance = new TooltipManager()\n\t\t}\n\t\treturn TooltipManager.instance\n\t}\n\n\tshowTooltip(\n\t\ttooltipId: string,\n\t\tcontent: string | React.ReactNode,\n\t\ttargetElement: HTMLElement,\n\t\tside: 'top' | 'right' | 'bottom' | 'left',\n\t\tsideOffset: number,\n\t\tshowOnMobile: boolean,\n\t\tdelayDuration: number\n\t) {\n\t\t// Clear any existing destroy timeout\n\t\tif (this.destroyTimeoutId) {\n\t\t\tclearTimeout(this.destroyTimeoutId)\n\t\t\tthis.destroyTimeoutId = null\n\t\t}\n\n\t\t// Update current tooltip\n\t\tthis.currentTooltip.set({\n\t\t\tid: tooltipId,\n\t\t\tcontent,\n\t\t\tside,\n\t\t\tsideOffset,\n\t\t\tshowOnMobile,\n\t\t\ttargetElement,\n\t\t\tdelayDuration,\n\t\t})\n\t}\n\n\thideTooltip(editor: Editor | null, tooltipId: string, instant: boolean = false) {\n\t\tconst hide = () => {\n\t\t\t// Only hide if this is the current tooltip\n\t\t\tif (this.currentTooltip.get()?.id === tooltipId) {\n\t\t\t\tthis.currentTooltip.set(null)\n\t\t\t\tthis.destroyTimeoutId = null\n\t\t\t}\n\t\t}\n\n\t\tif (editor && !instant) {\n\t\t\t// Start destroy timeout (1 second)\n\t\t\tthis.destroyTimeoutId = editor.timers.setTimeout(hide, 300)\n\t\t} else {\n\t\t\thide()\n\t\t}\n\t}\n\n\thideAllTooltips() {\n\t\tthis.currentTooltip.set(null)\n\t\tthis.destroyTimeoutId = null\n\t}\n\n\tgetCurrentTooltipData() {\n\t\tconst currentTooltip = this.currentTooltip.get()\n\t\tif (!currentTooltip) return null\n\t\tif (!this.supportsHover() && !currentTooltip.showOnMobile) return null\n\t\treturn currentTooltip\n\t}\n\n\tprivate supportsHoverAtom: Atom<boolean> | null = null\n\tsupportsHover() {\n\t\tif (!this.supportsHoverAtom) {\n\t\t\tconst mediaQuery = window.matchMedia('(hover: hover)')\n\t\t\tconst supportsHover = atom('has hover', mediaQuery.matches)\n\t\t\tthis.supportsHoverAtom = supportsHover\n\t\t\tmediaQuery.addEventListener('change', (e) => {\n\t\t\t\tsupportsHover.set(e.matches)\n\t\t\t})\n\t\t}\n\t\treturn this.supportsHoverAtom.get()\n\t}\n}\n\nexport const tooltipManager = TooltipManager.getInstance()\n\n// Context for the tooltip singleton\nconst TooltipSingletonContext = createContext<boolean>(false)\n\n/** @public */\nexport interface TldrawUiTooltipProviderProps {\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function TldrawUiTooltipProvider({ children }: TldrawUiTooltipProviderProps) {\n\treturn (\n\t\t<_Tooltip.Provider skipDelayDuration={700}>\n\t\t\t<TooltipSingletonContext.Provider value={true}>\n\t\t\t\t{children}\n\t\t\t\t<TooltipSingleton />\n\t\t\t</TooltipSingletonContext.Provider>\n\t\t</_Tooltip.Provider>\n\t)\n}\n\n// The singleton tooltip component that renders once\nfunction TooltipSingleton() {\n\tconst [isOpen, setIsOpen] = useState(false)\n\tconst triggerRef = useRef<HTMLDivElement>(null)\n\tconst isFirstShowRef = useRef(true)\n\tconst editor = useMaybeEditor()\n\n\tconst currentTooltip = useValue(\n\t\t'current tooltip',\n\t\t() => tooltipManager.getCurrentTooltipData(),\n\t\t[]\n\t)\n\n\tconst cameraState = useValue('camera state', () => editor?.getCameraState(), [editor])\n\n\t// Hide tooltip when camera is moving (panning/zooming)\n\tuseEffect(() => {\n\t\tif (cameraState === 'moving' && isOpen && currentTooltip) {\n\t\t\ttooltipManager.hideTooltip(editor, currentTooltip.id, true)\n\t\t}\n\t}, [cameraState, isOpen, currentTooltip, editor])\n\n\t// Update open state and trigger position\n\tuseEffect(() => {\n\t\tlet timer: ReturnType<typeof setTimeout> | null = null\n\t\tif (currentTooltip && triggerRef.current) {\n\t\t\t// Position the invisible trigger element over the active element\n\t\t\tconst activeRect = currentTooltip.targetElement.getBoundingClientRect()\n\t\t\tconst trigger = triggerRef.current\n\n\t\t\ttrigger.style.position = 'fixed'\n\t\t\ttrigger.style.left = `${activeRect.left}px`\n\t\t\ttrigger.style.top = `${activeRect.top}px`\n\t\t\ttrigger.style.width = `${activeRect.width}px`\n\t\t\ttrigger.style.height = `${activeRect.height}px`\n\t\t\ttrigger.style.pointerEvents = 'none'\n\t\t\ttrigger.style.zIndex = '9999'\n\n\t\t\t// Handle delay for first show\n\t\t\tif (isFirstShowRef.current) {\n\t\t\t\t// eslint-disable-next-line no-restricted-globals\n\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\tsetIsOpen(true)\n\t\t\t\t\tisFirstShowRef.current = false\n\t\t\t\t}, currentTooltip.delayDuration)\n\t\t\t} else {\n\t\t\t\t// Subsequent tooltips show immediately\n\t\t\t\tsetIsOpen(true)\n\t\t\t}\n\t\t} else {\n\t\t\t// Hide tooltip immediately\n\t\t\tsetIsOpen(false)\n\t\t\t// Reset first show state after tooltip is hidden\n\t\t\tisFirstShowRef.current = true\n\t\t}\n\n\t\treturn () => {\n\t\t\tif (timer !== null) {\n\t\t\t\tclearTimeout(timer)\n\t\t\t}\n\t\t}\n\t}, [currentTooltip])\n\n\tif (!currentTooltip) {\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<_Tooltip.Root open={isOpen} delayDuration={0}>\n\t\t\t<_Tooltip.Trigger asChild>\n\t\t\t\t<div ref={triggerRef} />\n\t\t\t</_Tooltip.Trigger>\n\t\t\t<_Tooltip.Content\n\t\t\t\tclassName=\"tlui-tooltip\"\n\t\t\t\tside={currentTooltip.side}\n\t\t\t\tsideOffset={currentTooltip.sideOffset}\n\t\t\t\tavoidCollisions\n\t\t\t\tcollisionPadding={8}\n\t\t\t\tdir=\"ltr\"\n\t\t\t>\n\t\t\t\t{currentTooltip.content}\n\t\t\t\t<_Tooltip.Arrow className=\"tlui-tooltip__arrow\" />\n\t\t\t</_Tooltip.Content>\n\t\t</_Tooltip.Root>\n\t)\n}\n\n/** @public @react */\nexport const TldrawUiTooltip = forwardRef<HTMLButtonElement, TldrawUiTooltipProps>(\n\t(\n\t\t{\n\t\t\tchildren,\n\t\t\tcontent,\n\t\t\tside,\n\t\t\tsideOffset = 5,\n\t\t\tdisabled = false,\n\t\t\tshowOnMobile = false,\n\t\t\tdelayDuration,\n\t\t},\n\t\tref\n\t) => {\n\t\tconst editor = useMaybeEditor()\n\t\tconst tooltipId = useRef<string>(uniqueId())\n\t\tconst hasProvider = useContext(TooltipSingletonContext)\n\n\t\tconst orientationCtx = useTldrawUiOrientation()\n\t\tconst sideToUse = side ?? orientationCtx.tooltipSide\n\n\t\tuseEffect(() => {\n\t\t\tconst currentTooltipId = tooltipId.current\n\t\t\treturn () => {\n\t\t\t\tif (hasProvider) {\n\t\t\t\t\ttooltipManager.hideTooltip(editor, currentTooltipId, true)\n\t\t\t\t}\n\t\t\t}\n\t\t}, [editor, hasProvider])\n\n\t\t// Don't show tooltip if disabled, no content, or UI labels are disabled\n\t\tif (disabled || !content) {\n\t\t\treturn <>{children}</>\n\t\t}\n\n\t\tconst delayDurationToUse =\n\t\t\tdelayDuration ?? (editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS)\n\n\t\t// Fallback to old behavior if no provider\n\t\tif (!hasProvider) {\n\t\t\treturn (\n\t\t\t\t<_Tooltip.Root delayDuration={delayDurationToUse} disableHoverableContent>\n\t\t\t\t\t<_Tooltip.Trigger asChild ref={ref}>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</_Tooltip.Trigger>\n\t\t\t\t\t<_Tooltip.Content\n\t\t\t\t\t\tclassName=\"tlui-tooltip\"\n\t\t\t\t\t\tside={sideToUse}\n\t\t\t\t\t\tsideOffset={sideOffset}\n\t\t\t\t\t\tavoidCollisions\n\t\t\t\t\t\tcollisionPadding={8}\n\t\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{content}\n\t\t\t\t\t\t<_Tooltip.Arrow className=\"tlui-tooltip__arrow\" />\n\t\t\t\t\t</_Tooltip.Content>\n\t\t\t\t</_Tooltip.Root>\n\t\t\t)\n\t\t}\n\n\t\tconst child = React.Children.only(children)\n\t\tassert(React.isValidElement(child), 'TldrawUiTooltip children must be a single element')\n\n\t\tconst handleMouseEnter = (event: React.MouseEvent<HTMLElement>) => {\n\t\t\tchild.props.onMouseEnter?.(event)\n\t\t\ttooltipManager.showTooltip(\n\t\t\t\ttooltipId.current,\n\t\t\t\tcontent,\n\t\t\t\tevent.currentTarget as HTMLElement,\n\t\t\t\tsideToUse,\n\t\t\t\tsideOffset,\n\t\t\t\tshowOnMobile,\n\t\t\t\tdelayDurationToUse\n\t\t\t)\n\t\t}\n\n\t\tconst handleMouseLeave = (event: React.MouseEvent<HTMLElement>) => {\n\t\t\tchild.props.onMouseLeave?.(event)\n\t\t\ttooltipManager.hideTooltip(editor, tooltipId.current)\n\t\t}\n\n\t\tconst handleFocus = (event: React.FocusEvent<HTMLElement>) => {\n\t\t\tchild.props.onFocus?.(event)\n\t\t\ttooltipManager.showTooltip(\n\t\t\t\ttooltipId.current,\n\t\t\t\tcontent,\n\t\t\t\tevent.currentTarget as HTMLElement,\n\t\t\t\tsideToUse,\n\t\t\t\tsideOffset,\n\t\t\t\tshowOnMobile,\n\t\t\t\tdelayDurationToUse\n\t\t\t)\n\t\t}\n\n\t\tconst handleBlur = (event: React.FocusEvent<HTMLElement>) => {\n\t\t\tchild.props.onBlur?.(event)\n\t\t\ttooltipManager.hideTooltip(editor, tooltipId.current)\n\t\t}\n\n\t\tconst childrenWithHandlers = React.cloneElement(children as React.ReactElement, {\n\t\t\tonMouseEnter: handleMouseEnter,\n\t\t\tonMouseLeave: handleMouseLeave,\n\t\t\tonFocus: handleFocus,\n\t\t\tonBlur: handleBlur,\n\t\t})\n\n\t\treturn childrenWithHandlers\n\t}\n)\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { assert, Atom, atom, Editor, uniqueId, useMaybeEditor, useValue } from '@tldraw/editor'\nimport { Tooltip as _Tooltip } from 'radix-ui'\nimport React, {\n\tcreateContext,\n\tforwardRef,\n\tReactNode,\n\tuseContext,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from 'react'\nimport { useTldrawUiOrientation } from './layout'\n\nconst DEFAULT_TOOLTIP_DELAY_MS = 700\n\n/** @public */\nexport interface TldrawUiTooltipProps {\n\tchildren: React.ReactNode\n\tcontent?: string | React.ReactNode\n\tside?: 'top' | 'right' | 'bottom' | 'left'\n\tsideOffset?: number\n\tdisabled?: boolean\n\tshowOnMobile?: boolean\n\tdelayDuration?: number\n}\n\ninterface CurrentTooltip {\n\tid: string\n\tcontent: ReactNode\n\tside: 'top' | 'right' | 'bottom' | 'left'\n\tsideOffset: number\n\tshowOnMobile: boolean\n\ttargetElement: HTMLElement\n\tdelayDuration: number\n}\n\n// Singleton tooltip manager\nclass TooltipManager {\n\tprivate static instance: TooltipManager | null = null\n\tprivate currentTooltip = atom<CurrentTooltip | null>('current tooltip', null)\n\tprivate destroyTimeoutId: number | null = null\n\n\tstatic getInstance(): TooltipManager {\n\t\tif (!TooltipManager.instance) {\n\t\t\tTooltipManager.instance = new TooltipManager()\n\t\t}\n\t\treturn TooltipManager.instance\n\t}\n\n\tshowTooltip(\n\t\ttooltipId: string,\n\t\tcontent: string | React.ReactNode,\n\t\ttargetElement: HTMLElement,\n\t\tside: 'top' | 'right' | 'bottom' | 'left',\n\t\tsideOffset: number,\n\t\tshowOnMobile: boolean,\n\t\tdelayDuration: number\n\t) {\n\t\t// Clear any existing destroy timeout\n\t\tif (this.destroyTimeoutId) {\n\t\t\tclearTimeout(this.destroyTimeoutId)\n\t\t\tthis.destroyTimeoutId = null\n\t\t}\n\n\t\t// Update current tooltip\n\t\tthis.currentTooltip.set({\n\t\t\tid: tooltipId,\n\t\t\tcontent,\n\t\t\tside,\n\t\t\tsideOffset,\n\t\t\tshowOnMobile,\n\t\t\ttargetElement,\n\t\t\tdelayDuration,\n\t\t})\n\t}\n\n\tupdateCurrentTooltip(tooltipId: string, update: (tooltip: CurrentTooltip) => CurrentTooltip) {\n\t\tthis.currentTooltip.update((tooltip) => {\n\t\t\tif (tooltip?.id === tooltipId) {\n\t\t\t\treturn update(tooltip)\n\t\t\t}\n\t\t\treturn tooltip\n\t\t})\n\t}\n\n\thideTooltip(editor: Editor | null, tooltipId: string, instant: boolean = false) {\n\t\tconst hide = () => {\n\t\t\t// Only hide if this is the current tooltip\n\t\t\tif (this.currentTooltip.get()?.id === tooltipId) {\n\t\t\t\tthis.currentTooltip.set(null)\n\t\t\t\tthis.destroyTimeoutId = null\n\t\t\t}\n\t\t}\n\n\t\tif (editor && !instant) {\n\t\t\t// Start destroy timeout (1 second)\n\t\t\tthis.destroyTimeoutId = editor.timers.setTimeout(hide, 300)\n\t\t} else {\n\t\t\thide()\n\t\t}\n\t}\n\n\thideAllTooltips() {\n\t\tthis.currentTooltip.set(null)\n\t\tthis.destroyTimeoutId = null\n\t}\n\n\tgetCurrentTooltipData() {\n\t\tconst currentTooltip = this.currentTooltip.get()\n\t\tif (!currentTooltip) return null\n\t\tif (!this.supportsHover() && !currentTooltip.showOnMobile) return null\n\t\treturn currentTooltip\n\t}\n\n\tprivate supportsHoverAtom: Atom<boolean> | null = null\n\tsupportsHover() {\n\t\tif (!this.supportsHoverAtom) {\n\t\t\tconst mediaQuery = window.matchMedia('(hover: hover)')\n\t\t\tconst supportsHover = atom('has hover', mediaQuery.matches)\n\t\t\tthis.supportsHoverAtom = supportsHover\n\t\t\tmediaQuery.addEventListener('change', (e) => {\n\t\t\t\tsupportsHover.set(e.matches)\n\t\t\t})\n\t\t}\n\t\treturn this.supportsHoverAtom.get()\n\t}\n}\n\nexport const tooltipManager = TooltipManager.getInstance()\n\n// Context for the tooltip singleton\nconst TooltipSingletonContext = createContext<boolean>(false)\n\n/** @public */\nexport interface TldrawUiTooltipProviderProps {\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function TldrawUiTooltipProvider({ children }: TldrawUiTooltipProviderProps) {\n\treturn (\n\t\t<_Tooltip.Provider skipDelayDuration={700}>\n\t\t\t<TooltipSingletonContext.Provider value={true}>\n\t\t\t\t{children}\n\t\t\t\t<TooltipSingleton />\n\t\t\t</TooltipSingletonContext.Provider>\n\t\t</_Tooltip.Provider>\n\t)\n}\n\n// The singleton tooltip component that renders once\nfunction TooltipSingleton() {\n\tconst [isOpen, setIsOpen] = useState(false)\n\tconst triggerRef = useRef<HTMLDivElement>(null)\n\tconst isFirstShowRef = useRef(true)\n\tconst editor = useMaybeEditor()\n\n\tconst currentTooltip = useValue(\n\t\t'current tooltip',\n\t\t() => tooltipManager.getCurrentTooltipData(),\n\t\t[]\n\t)\n\n\tconst cameraState = useValue('camera state', () => editor?.getCameraState(), [editor])\n\n\t// Hide tooltip when camera is moving (panning/zooming)\n\tuseEffect(() => {\n\t\tif (cameraState === 'moving' && isOpen && currentTooltip) {\n\t\t\ttooltipManager.hideTooltip(editor, currentTooltip.id, true)\n\t\t}\n\t}, [cameraState, isOpen, currentTooltip, editor])\n\n\tuseEffect(() => {\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (event.key === 'Escape' && currentTooltip && isOpen) {\n\t\t\t\ttooltipManager.hideTooltip(editor, currentTooltip.id)\n\t\t\t\tevent.stopPropagation()\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener('keydown', handleKeyDown, { capture: true })\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('keydown', handleKeyDown, { capture: true })\n\t\t}\n\t}, [editor, currentTooltip, isOpen])\n\n\t// Update open state and trigger position\n\tuseEffect(() => {\n\t\tlet timer: ReturnType<typeof setTimeout> | null = null\n\t\tif (currentTooltip && triggerRef.current) {\n\t\t\t// Position the invisible trigger element over the active element\n\t\t\tconst activeRect = currentTooltip.targetElement.getBoundingClientRect()\n\t\t\tconst trigger = triggerRef.current\n\n\t\t\ttrigger.style.position = 'fixed'\n\t\t\ttrigger.style.left = `${activeRect.left}px`\n\t\t\ttrigger.style.top = `${activeRect.top}px`\n\t\t\ttrigger.style.width = `${activeRect.width}px`\n\t\t\ttrigger.style.height = `${activeRect.height}px`\n\t\t\ttrigger.style.pointerEvents = 'none'\n\t\t\ttrigger.style.zIndex = '9999'\n\n\t\t\t// Handle delay for first show\n\t\t\tif (isFirstShowRef.current) {\n\t\t\t\t// eslint-disable-next-line no-restricted-globals\n\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\tsetIsOpen(true)\n\t\t\t\t\tisFirstShowRef.current = false\n\t\t\t\t}, currentTooltip.delayDuration)\n\t\t\t} else {\n\t\t\t\t// Subsequent tooltips show immediately\n\t\t\t\tsetIsOpen(true)\n\t\t\t}\n\t\t} else {\n\t\t\t// Hide tooltip immediately\n\t\t\tsetIsOpen(false)\n\t\t\t// Reset first show state after tooltip is hidden\n\t\t\tisFirstShowRef.current = true\n\t\t}\n\n\t\treturn () => {\n\t\t\tif (timer !== null) {\n\t\t\t\tclearTimeout(timer)\n\t\t\t}\n\t\t}\n\t}, [currentTooltip])\n\n\tif (!currentTooltip) {\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<_Tooltip.Root open={isOpen} delayDuration={0}>\n\t\t\t<_Tooltip.Trigger asChild>\n\t\t\t\t<div ref={triggerRef} />\n\t\t\t</_Tooltip.Trigger>\n\t\t\t<_Tooltip.Content\n\t\t\t\tclassName=\"tlui-tooltip\"\n\t\t\t\tside={currentTooltip.side}\n\t\t\t\tsideOffset={currentTooltip.sideOffset}\n\t\t\t\tavoidCollisions\n\t\t\t\tcollisionPadding={8}\n\t\t\t\tdir=\"ltr\"\n\t\t\t>\n\t\t\t\t{currentTooltip.content}\n\t\t\t\t<_Tooltip.Arrow className=\"tlui-tooltip__arrow\" />\n\t\t\t</_Tooltip.Content>\n\t\t</_Tooltip.Root>\n\t)\n}\n\n/** @public @react */\nexport const TldrawUiTooltip = forwardRef<HTMLButtonElement, TldrawUiTooltipProps>(\n\t(\n\t\t{\n\t\t\tchildren,\n\t\t\tcontent,\n\t\t\tside,\n\t\t\tsideOffset = 5,\n\t\t\tdisabled = false,\n\t\t\tshowOnMobile = false,\n\t\t\tdelayDuration,\n\t\t},\n\t\tref\n\t) => {\n\t\tconst editor = useMaybeEditor()\n\t\tconst tooltipId = useRef<string>(uniqueId())\n\t\tconst hasProvider = useContext(TooltipSingletonContext)\n\t\tconst enhancedA11yMode = useValue(\n\t\t\t'enhancedA11yMode',\n\t\t\t() => editor?.user.getEnhancedA11yMode(),\n\t\t\t[editor]\n\t\t)\n\n\t\tconst orientationCtx = useTldrawUiOrientation()\n\t\tconst sideToUse = side ?? orientationCtx.tooltipSide\n\n\t\tuseEffect(() => {\n\t\t\tconst currentTooltipId = tooltipId.current\n\t\t\treturn () => {\n\t\t\t\tif (hasProvider) {\n\t\t\t\t\ttooltipManager.hideTooltip(editor, currentTooltipId, true)\n\t\t\t\t}\n\t\t\t}\n\t\t}, [editor, hasProvider])\n\n\t\tuseLayoutEffect(() => {\n\t\t\tif (hasProvider && tooltipManager.getCurrentTooltipData()?.id === tooltipId.current) {\n\t\t\t\ttooltipManager.updateCurrentTooltip(tooltipId.current, (tooltip) => ({\n\t\t\t\t\t...tooltip,\n\t\t\t\t\tcontent,\n\t\t\t\t\tside: sideToUse,\n\t\t\t\t\tsideOffset,\n\t\t\t\t\tshowOnMobile,\n\t\t\t\t}))\n\t\t\t}\n\t\t}, [content, sideToUse, sideOffset, showOnMobile, hasProvider])\n\n\t\t// Don't show tooltip if disabled, no content, or enhanced accessibility mode is disabled\n\t\tif (disabled || !content) {\n\t\t\treturn <>{children}</>\n\t\t}\n\n\t\tlet delayDurationToUse\n\t\tif (enhancedA11yMode) {\n\t\t\tdelayDurationToUse = 0\n\t\t} else {\n\t\t\tdelayDurationToUse =\n\t\t\t\tdelayDuration ?? (editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS)\n\t\t}\n\n\t\t// Fallback to old behavior if no provider\n\t\tif (!hasProvider || enhancedA11yMode) {\n\t\t\treturn (\n\t\t\t\t<_Tooltip.Root\n\t\t\t\t\tdelayDuration={delayDurationToUse}\n\t\t\t\t\tdisableHoverableContent={!enhancedA11yMode}\n\t\t\t\t>\n\t\t\t\t\t<_Tooltip.Trigger asChild ref={ref}>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</_Tooltip.Trigger>\n\t\t\t\t\t<_Tooltip.Content\n\t\t\t\t\t\tclassName=\"tlui-tooltip\"\n\t\t\t\t\t\tside={sideToUse}\n\t\t\t\t\t\tsideOffset={sideOffset}\n\t\t\t\t\t\tavoidCollisions\n\t\t\t\t\t\tcollisionPadding={8}\n\t\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{content}\n\t\t\t\t\t\t<_Tooltip.Arrow className=\"tlui-tooltip__arrow\" />\n\t\t\t\t\t</_Tooltip.Content>\n\t\t\t\t</_Tooltip.Root>\n\t\t\t)\n\t\t}\n\n\t\tconst child = React.Children.only(children)\n\t\tassert(React.isValidElement(child), 'TldrawUiTooltip children must be a single element')\n\n\t\tconst handleMouseEnter = (event: React.MouseEvent<HTMLElement>) => {\n\t\t\tchild.props.onMouseEnter?.(event)\n\t\t\ttooltipManager.showTooltip(\n\t\t\t\ttooltipId.current,\n\t\t\t\tcontent,\n\t\t\t\tevent.currentTarget as HTMLElement,\n\t\t\t\tsideToUse,\n\t\t\t\tsideOffset,\n\t\t\t\tshowOnMobile,\n\t\t\t\tdelayDurationToUse\n\t\t\t)\n\t\t}\n\n\t\tconst handleMouseLeave = (event: React.MouseEvent<HTMLElement>) => {\n\t\t\tchild.props.onMouseLeave?.(event)\n\t\t\ttooltipManager.hideTooltip(editor, tooltipId.current)\n\t\t}\n\n\t\tconst handleFocus = (event: React.FocusEvent<HTMLElement>) => {\n\t\t\tchild.props.onFocus?.(event)\n\t\t\ttooltipManager.showTooltip(\n\t\t\t\ttooltipId.current,\n\t\t\t\tcontent,\n\t\t\t\tevent.currentTarget as HTMLElement,\n\t\t\t\tsideToUse,\n\t\t\t\tsideOffset,\n\t\t\t\tshowOnMobile,\n\t\t\t\tdelayDurationToUse\n\t\t\t)\n\t\t}\n\n\t\tconst handleBlur = (event: React.FocusEvent<HTMLElement>) => {\n\t\t\tchild.props.onBlur?.(event)\n\t\t\ttooltipManager.hideTooltip(editor, tooltipId.current)\n\t\t}\n\n\t\tconst childrenWithHandlers = React.cloneElement(children as React.ReactElement, {\n\t\t\tonMouseEnter: handleMouseEnter,\n\t\t\tonMouseLeave: handleMouseLeave,\n\t\t\tonFocus: handleFocus,\n\t\t\tonBlur: handleBlur,\n\t\t})\n\n\t\treturn childrenWithHandlers\n\t}\n)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -11,6 +11,7 @@ function TldrawUiMenuCheckboxItem({
|
|
|
11
11
|
id,
|
|
12
12
|
kbd,
|
|
13
13
|
label,
|
|
14
|
+
lang,
|
|
14
15
|
readonlyOk,
|
|
15
16
|
onSelect,
|
|
16
17
|
toggle = false,
|
|
@@ -29,6 +30,7 @@ function TldrawUiMenuCheckboxItem({
|
|
|
29
30
|
_DropdownMenu.CheckboxItem,
|
|
30
31
|
{
|
|
31
32
|
dir: "ltr",
|
|
33
|
+
lang,
|
|
32
34
|
className: "tlui-button tlui-button__menu tlui-button__checkbox",
|
|
33
35
|
title: labelStr,
|
|
34
36
|
onSelect: (e) => {
|
|
@@ -58,6 +60,7 @@ function TldrawUiMenuCheckboxItem({
|
|
|
58
60
|
{
|
|
59
61
|
className: "tlui-button tlui-button__menu tlui-button__checkbox",
|
|
60
62
|
dir: "ltr",
|
|
63
|
+
lang,
|
|
61
64
|
title: labelStr,
|
|
62
65
|
onSelect: (e) => {
|
|
63
66
|
onSelect(sourceId);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx"],
|
|
4
|
-
"sourcesContent": ["import { preventDefault } from '@tldraw/editor'\nimport { ContextMenu as _ContextMenu, DropdownMenu as _DropdownMenu } from 'radix-ui'\nimport { unwrapLabel } from '../../../context/actions'\nimport { TLUiEventSource } from '../../../context/events'\nimport { useReadonly } from '../../../hooks/useReadonly'\nimport { TLUiTranslationKey } from '../../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../../hooks/useTranslation/useTranslation'\nimport { TldrawUiIcon, TLUiIconJsx } from '../TldrawUiIcon'\nimport { TldrawUiKbd } from '../TldrawUiKbd'\nimport { useTldrawUiMenuContext } from './TldrawUiMenuContext'\n\n/** @public */\nexport interface TLUiMenuCheckboxItemProps<\n\tTranslationKey extends string = string,\n\tIconType extends string = string,\n> {\n\ticon?: IconType | TLUiIconJsx\n\tid: string\n\tkbd?: string\n\ttitle?: string\n\tlabel?: TranslationKey | { [key: string]: TranslationKey }\n\treadonlyOk?: boolean\n\tonSelect(source: TLUiEventSource): Promise<void> | void\n\ttoggle?: boolean\n\tchecked?: boolean\n\tdisabled?: boolean\n}\n\n/** @public @react */\nexport function TldrawUiMenuCheckboxItem<\n\tTranslationKey extends string = string,\n\tIconType extends string = string,\n>({\n\tid,\n\tkbd,\n\tlabel,\n\treadonlyOk,\n\tonSelect,\n\ttoggle = false,\n\tdisabled = false,\n\tchecked = false,\n}: TLUiMenuCheckboxItemProps<TranslationKey, IconType>) {\n\tconst { type: menuType, sourceId } = useTldrawUiMenuContext()\n\tconst isReadonlyMode = useReadonly()\n\tconst msg = useTranslation()\n\n\t// If the editor is in readonly mode and the item is not marked as readonlyok, return null\n\tif (isReadonlyMode && !readonlyOk) return null\n\n\tconst labelToUse = unwrapLabel(label, menuType)\n\tconst labelStr = labelToUse ? msg(labelToUse as TLUiTranslationKey) : undefined\n\n\tswitch (menuType) {\n\t\tcase 'menu': {\n\t\t\treturn (\n\t\t\t\t<_DropdownMenu.CheckboxItem\n\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\tclassName=\"tlui-button tlui-button__menu tlui-button__checkbox\"\n\t\t\t\t\ttitle={labelStr}\n\t\t\t\t\tonSelect={(e) => {\n\t\t\t\t\t\tonSelect?.(sourceId)\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tchecked={checked}\n\t\t\t\t>\n\t\t\t\t\t<TldrawUiIcon\n\t\t\t\t\t\tsmall\n\t\t\t\t\t\tlabel={msg(checked ? 'ui.checked' : 'ui.unchecked')}\n\t\t\t\t\t\ticon={toggle ? (checked ? 'toggle-on' : 'toggle-off') : checked ? 'check' : 'none'}\n\t\t\t\t\t/>\n\t\t\t\t\t{labelStr && (\n\t\t\t\t\t\t<span className=\"tlui-button__label\" draggable={false}>\n\t\t\t\t\t\t\t{labelStr}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)}\n\t\t\t\t\t{kbd && <TldrawUiKbd>{kbd}</TldrawUiKbd>}\n\t\t\t\t</_DropdownMenu.CheckboxItem>\n\t\t\t)\n\t\t}\n\t\tcase 'context-menu': {\n\t\t\treturn (\n\t\t\t\t<_ContextMenu.CheckboxItem\n\t\t\t\t\tkey={id}\n\t\t\t\t\tclassName=\"tlui-button tlui-button__menu tlui-button__checkbox\"\n\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\ttitle={labelStr}\n\t\t\t\t\tonSelect={(e) => {\n\t\t\t\t\t\tonSelect(sourceId)\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tchecked={checked}\n\t\t\t\t>\n\t\t\t\t\t<TldrawUiIcon\n\t\t\t\t\t\tsmall\n\t\t\t\t\t\tlabel={msg(checked ? 'ui.checked' : 'ui.unchecked')}\n\t\t\t\t\t\ticon={toggle ? (checked ? 'toggle-on' : 'toggle-off') : checked ? 'check' : 'none'}\n\t\t\t\t\t/>\n\t\t\t\t\t{labelStr && (\n\t\t\t\t\t\t<span className=\"tlui-button__label\" draggable={false}>\n\t\t\t\t\t\t\t{labelStr}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)}\n\t\t\t\t\t{kbd && <TldrawUiKbd>{kbd}</TldrawUiKbd>}\n\t\t\t\t</_ContextMenu.CheckboxItem>\n\t\t\t)\n\t\t}\n\t\tdefault: {\n\t\t\t// no checkbox items in actions menu\n\t\t\treturn null\n\t\t}\n\t}\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { preventDefault } from '@tldraw/editor'\nimport { ContextMenu as _ContextMenu, DropdownMenu as _DropdownMenu } from 'radix-ui'\nimport { unwrapLabel } from '../../../context/actions'\nimport { TLUiEventSource } from '../../../context/events'\nimport { useReadonly } from '../../../hooks/useReadonly'\nimport { TLUiTranslationKey } from '../../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../../hooks/useTranslation/useTranslation'\nimport { TldrawUiIcon, TLUiIconJsx } from '../TldrawUiIcon'\nimport { TldrawUiKbd } from '../TldrawUiKbd'\nimport { useTldrawUiMenuContext } from './TldrawUiMenuContext'\n\n/** @public */\nexport interface TLUiMenuCheckboxItemProps<\n\tTranslationKey extends string = string,\n\tIconType extends string = string,\n> {\n\ticon?: IconType | TLUiIconJsx\n\tid: string\n\tkbd?: string\n\ttitle?: string\n\tlabel?: TranslationKey | { [key: string]: TranslationKey }\n\tlang?: string\n\treadonlyOk?: boolean\n\tonSelect(source: TLUiEventSource): Promise<void> | void\n\ttoggle?: boolean\n\tchecked?: boolean\n\tdisabled?: boolean\n}\n\n/** @public @react */\nexport function TldrawUiMenuCheckboxItem<\n\tTranslationKey extends string = string,\n\tIconType extends string = string,\n>({\n\tid,\n\tkbd,\n\tlabel,\n\tlang,\n\treadonlyOk,\n\tonSelect,\n\ttoggle = false,\n\tdisabled = false,\n\tchecked = false,\n}: TLUiMenuCheckboxItemProps<TranslationKey, IconType>) {\n\tconst { type: menuType, sourceId } = useTldrawUiMenuContext()\n\tconst isReadonlyMode = useReadonly()\n\tconst msg = useTranslation()\n\n\t// If the editor is in readonly mode and the item is not marked as readonlyok, return null\n\tif (isReadonlyMode && !readonlyOk) return null\n\n\tconst labelToUse = unwrapLabel(label, menuType)\n\tconst labelStr = labelToUse ? msg(labelToUse as TLUiTranslationKey) : undefined\n\n\tswitch (menuType) {\n\t\tcase 'menu': {\n\t\t\treturn (\n\t\t\t\t<_DropdownMenu.CheckboxItem\n\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\tlang={lang}\n\t\t\t\t\tclassName=\"tlui-button tlui-button__menu tlui-button__checkbox\"\n\t\t\t\t\ttitle={labelStr}\n\t\t\t\t\tonSelect={(e) => {\n\t\t\t\t\t\tonSelect?.(sourceId)\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tchecked={checked}\n\t\t\t\t>\n\t\t\t\t\t<TldrawUiIcon\n\t\t\t\t\t\tsmall\n\t\t\t\t\t\tlabel={msg(checked ? 'ui.checked' : 'ui.unchecked')}\n\t\t\t\t\t\ticon={toggle ? (checked ? 'toggle-on' : 'toggle-off') : checked ? 'check' : 'none'}\n\t\t\t\t\t/>\n\t\t\t\t\t{labelStr && (\n\t\t\t\t\t\t<span className=\"tlui-button__label\" draggable={false}>\n\t\t\t\t\t\t\t{labelStr}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)}\n\t\t\t\t\t{kbd && <TldrawUiKbd>{kbd}</TldrawUiKbd>}\n\t\t\t\t</_DropdownMenu.CheckboxItem>\n\t\t\t)\n\t\t}\n\t\tcase 'context-menu': {\n\t\t\treturn (\n\t\t\t\t<_ContextMenu.CheckboxItem\n\t\t\t\t\tkey={id}\n\t\t\t\t\tclassName=\"tlui-button tlui-button__menu tlui-button__checkbox\"\n\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\tlang={lang}\n\t\t\t\t\ttitle={labelStr}\n\t\t\t\t\tonSelect={(e) => {\n\t\t\t\t\t\tonSelect(sourceId)\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tchecked={checked}\n\t\t\t\t>\n\t\t\t\t\t<TldrawUiIcon\n\t\t\t\t\t\tsmall\n\t\t\t\t\t\tlabel={msg(checked ? 'ui.checked' : 'ui.unchecked')}\n\t\t\t\t\t\ticon={toggle ? (checked ? 'toggle-on' : 'toggle-off') : checked ? 'check' : 'none'}\n\t\t\t\t\t/>\n\t\t\t\t\t{labelStr && (\n\t\t\t\t\t\t<span className=\"tlui-button__label\" draggable={false}>\n\t\t\t\t\t\t\t{labelStr}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)}\n\t\t\t\t\t{kbd && <TldrawUiKbd>{kbd}</TldrawUiKbd>}\n\t\t\t\t</_ContextMenu.CheckboxItem>\n\t\t\t)\n\t\t}\n\t\tdefault: {\n\t\t\t// no checkbox items in actions menu\n\t\t\treturn null\n\t\t}\n\t}\n}\n"],
|
|
5
|
+
"mappings": "AAyDI,SAYC,KAZD;AAzDJ,SAAS,sBAAsB;AAC/B,SAAS,eAAe,cAAc,gBAAgB,qBAAqB;AAC3E,SAAS,mBAAmB;AAE5B,SAAS,mBAAmB;AAE5B,SAAS,sBAAsB;AAC/B,SAAS,oBAAiC;AAC1C,SAAS,mBAAmB;AAC5B,SAAS,8BAA8B;AAqBhC,SAAS,yBAGd;AAAA,EACD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,WAAW;AAAA,EACX,UAAU;AACX,GAAwD;AACvD,QAAM,EAAE,MAAM,UAAU,SAAS,IAAI,uBAAuB;AAC5D,QAAM,iBAAiB,YAAY;AACnC,QAAM,MAAM,eAAe;AAG3B,MAAI,kBAAkB,CAAC,WAAY,QAAO;AAE1C,QAAM,aAAa,YAAY,OAAO,QAAQ;AAC9C,QAAM,WAAW,aAAa,IAAI,UAAgC,IAAI;AAEtE,UAAQ,UAAU;AAAA,IACjB,KAAK,QAAQ;AACZ,aACC;AAAA,QAAC,cAAc;AAAA,QAAd;AAAA,UACA,KAAI;AAAA,UACJ;AAAA,UACA,WAAU;AAAA,UACV,OAAO;AAAA,UACP,UAAU,CAAC,MAAM;AAChB,uBAAW,QAAQ;AACnB,2BAAe,CAAC;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,UAEA;AAAA;AAAA,cAAC;AAAA;AAAA,gBACA,OAAK;AAAA,gBACL,OAAO,IAAI,UAAU,eAAe,cAAc;AAAA,gBAClD,MAAM,SAAU,UAAU,cAAc,eAAgB,UAAU,UAAU;AAAA;AAAA,YAC7E;AAAA,YACC,YACA,oBAAC,UAAK,WAAU,sBAAqB,WAAW,OAC9C,oBACF;AAAA,YAEA,OAAO,oBAAC,eAAa,eAAI;AAAA;AAAA;AAAA,MAC3B;AAAA,IAEF;AAAA,IACA,KAAK,gBAAgB;AACpB,aACC;AAAA,QAAC,aAAa;AAAA,QAAb;AAAA,UAEA,WAAU;AAAA,UACV,KAAI;AAAA,UACJ;AAAA,UACA,OAAO;AAAA,UACP,UAAU,CAAC,MAAM;AAChB,qBAAS,QAAQ;AACjB,2BAAe,CAAC;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,UAEA;AAAA;AAAA,cAAC;AAAA;AAAA,gBACA,OAAK;AAAA,gBACL,OAAO,IAAI,UAAU,eAAe,cAAc;AAAA,gBAClD,MAAM,SAAU,UAAU,cAAc,eAAgB,UAAU,UAAU;AAAA;AAAA,YAC7E;AAAA,YACC,YACA,oBAAC,UAAK,WAAU,sBAAqB,WAAW,OAC9C,oBACF;AAAA,YAEA,OAAO,oBAAC,eAAa,eAAI;AAAA;AAAA;AAAA,QAtBrB;AAAA,MAuBN;AAAA,IAEF;AAAA,IACA,SAAS;AAER,aAAO;AAAA,IACR;AAAA,EACD;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -137,7 +137,7 @@ function TldrawUiMenuItem({
|
|
|
137
137
|
icon,
|
|
138
138
|
onSelect,
|
|
139
139
|
onDragStart,
|
|
140
|
-
|
|
140
|
+
labelStr,
|
|
141
141
|
titleStr,
|
|
142
142
|
disabled,
|
|
143
143
|
isSelected
|
|
@@ -172,7 +172,7 @@ function TldrawUiMenuItem({
|
|
|
172
172
|
icon,
|
|
173
173
|
onSelect,
|
|
174
174
|
onDragStart,
|
|
175
|
-
|
|
175
|
+
labelStr,
|
|
176
176
|
titleStr,
|
|
177
177
|
disabled,
|
|
178
178
|
isSelected,
|
|
@@ -228,7 +228,7 @@ function useDraggableEvents(onDragStart, onSelect) {
|
|
|
228
228
|
type: "pointer",
|
|
229
229
|
target: "canvas",
|
|
230
230
|
name: "pointer_down",
|
|
231
|
-
...getPointerInfo(e),
|
|
231
|
+
...getPointerInfo(editor, e),
|
|
232
232
|
point: screenSpaceStart
|
|
233
233
|
});
|
|
234
234
|
editor.selectNone();
|
|
@@ -236,7 +236,7 @@ function useDraggableEvents(onDragStart, onSelect) {
|
|
|
236
236
|
type: "pointer",
|
|
237
237
|
target: "canvas",
|
|
238
238
|
name: "pointer_move",
|
|
239
|
-
...getPointerInfo(e),
|
|
239
|
+
...getPointerInfo(editor, e),
|
|
240
240
|
point: screenSpaceStart
|
|
241
241
|
});
|
|
242
242
|
tooltipManager.hideAllTooltips();
|
|
@@ -252,7 +252,7 @@ function useDraggableEvents(onDragStart, onSelect) {
|
|
|
252
252
|
type: "pointer",
|
|
253
253
|
target: "canvas",
|
|
254
254
|
name: "pointer_up",
|
|
255
|
-
...getPointerInfo(e)
|
|
255
|
+
...getPointerInfo(editor, e)
|
|
256
256
|
});
|
|
257
257
|
}
|
|
258
258
|
function handleClick() {
|
|
@@ -274,7 +274,7 @@ function useDraggableEvents(onDragStart, onSelect) {
|
|
|
274
274
|
}
|
|
275
275
|
function DraggableToolbarButton({
|
|
276
276
|
id,
|
|
277
|
-
|
|
277
|
+
labelStr,
|
|
278
278
|
titleStr,
|
|
279
279
|
disabled,
|
|
280
280
|
isSelected,
|
|
@@ -288,7 +288,7 @@ function DraggableToolbarButton({
|
|
|
288
288
|
return /* @__PURE__ */ jsx(
|
|
289
289
|
TldrawUiToolbarButton,
|
|
290
290
|
{
|
|
291
|
-
"aria-label":
|
|
291
|
+
"aria-label": labelStr,
|
|
292
292
|
"aria-pressed": isSelected ? "true" : "false",
|
|
293
293
|
isActive: isSelected,
|
|
294
294
|
className: "tlui-button-grid__button",
|
|
@@ -305,7 +305,7 @@ function DraggableToolbarButton({
|
|
|
305
305
|
return /* @__PURE__ */ jsx(
|
|
306
306
|
TldrawUiToolbarButton,
|
|
307
307
|
{
|
|
308
|
-
"aria-label":
|
|
308
|
+
"aria-label": labelStr,
|
|
309
309
|
"aria-pressed": isSelected ? "true" : "false",
|
|
310
310
|
"data-testid": `tools.${id}`,
|
|
311
311
|
"data-value": id,
|