Merge pull request #34512 from overleaf/mj-floating-toolbar-option

[web] Add setting for floating toolbar menu

GitOrigin-RevId: bd28f1f287f2011535c7fd530f1217f01e0cfbbc
This commit is contained in:
Mathias Jakobsen
2026-06-18 08:07:33 +00:00
committed by Copybot
parent 106dd1b07b
commit 5f79c2dd10
17 changed files with 237 additions and 5 deletions
@@ -28,6 +28,7 @@ import { useFeatureFlag } from '@/shared/context/split-test-context'
import { useEditorOpenDocContext } from '@/features/ide-react/context/editor-open-doc-context'
import { useEditorPropertiesContext } from '@/features/ide-react/context/editor-properties-context'
import UpgradeTrackChangesModal from '@/features/review-panel/components/upgrade-track-changes-modal'
import { useUserSettingsContext } from '@/shared/context/user-settings-context'
// TODO: remove this when definitely no longer used
export * from './codemirror-context'
@@ -95,6 +96,9 @@ function CodeMirrorEditorComponents({
}: CodeMirrorEditorComponentsProps) {
useToolbarMenuBarEditorCommands()
const { features } = useProjectContext()
const {
userSettings: { floatingMenu },
} = useUserSettingsContext()
const writefullToolbarMigrationEnabled = useFeatureFlag(
'writefull-toolbar-migration'
)
@@ -109,7 +113,8 @@ function CodeMirrorEditorComponents({
<MathPreviewTooltip />
<EditorContextMenu />
{features.trackChangesVisible &&
{floatingMenu &&
features.trackChangesVisible &&
(writefullToolbarMigrationEnabled ? (
<>
<AddCommentCommand />
@@ -159,7 +159,10 @@ export const createExtensions = (options: Record<string, any>): Extension[] => [
trackDetachedComments(options.currentDoc),
visual(options.docName, options.visual),
mathPreview(options.settings.mathPreview),
reviewTooltip(options.editorContextMenuEnabled),
reviewTooltip(
options.settings.floatingMenu,
options.editorContextMenuEnabled
),
contextMenu(options.editorContextMenuEnabled),
toolbarPanel(),
breadcrumbPanel(),
@@ -14,6 +14,8 @@ import {
SelectionRange,
EditorState,
Transaction,
Compartment,
TransactionSpec,
} from '@codemirror/state'
import { v4 as uuid } from 'uuid'
import { isContextMenuMouseEvent } from '../utils/context-menu-mouse-event'
@@ -52,7 +54,29 @@ export const buildAddNewCommentRangeEffect = (range: SelectionRange) => {
)
}
export const reviewTooltip = (editorContextMenuEnabled = false): Extension => {
const reviewTooltipCompartment = new Compartment()
export const reviewTooltip = (
enabled: boolean,
editorContextMenuEnabled: boolean = false
): Extension => {
return reviewTooltipCompartment.of(
enabled ? reviewTooltipEnabled(editorContextMenuEnabled) : []
)
}
export const setReviewTooltip = (
enabled: boolean,
editorContextMenuEnabled: boolean
): TransactionSpec => ({
effects: reviewTooltipCompartment.reconfigure(
enabled ? reviewTooltipEnabled(editorContextMenuEnabled) : []
),
})
export const reviewTooltipEnabled = (
editorContextMenuEnabled = false
): Extension => {
let mouseUpListener: null | (() => void) = null
const disableMouseUpListener = () => {
if (mouseUpListener) {
@@ -65,6 +65,7 @@ import { useActiveEditorTheme } from '@/shared/hooks/use-active-editor-theme'
import { useFeatureFlag } from '@/shared/context/split-test-context'
import { isCmVisualEditorAvailable } from '../utils/visual-editor'
import { setEditorTabs } from '../extensions/tabs-listener'
import { setReviewTooltip } from '../extensions/review-tooltip'
function useCodeMirrorScope(view: EditorView) {
const { fileTreeData } = useFileTreeData()
@@ -93,6 +94,7 @@ function useCodeMirrorScope(view: EditorView) {
editorTabs,
nonBlinkingCursor,
referencesSearchMode,
floatingMenu,
} = userSettings
const activeOverallTheme = useActiveOverallTheme()
const editorTheme = useActiveEditorTheme()
@@ -165,6 +167,7 @@ function useCodeMirrorScope(view: EditorView) {
editorTabs,
nonBlinkingCursor,
referencesSearchMode,
floatingMenu,
})
const currentDocRef = useRef({
@@ -481,6 +484,15 @@ function useCodeMirrorScope(view: EditorView) {
})
}, [view, editorTabs])
useEffect(() => {
settingsRef.current.floatingMenu = floatingMenu
window.setTimeout(() => {
view.dispatch(
setReviewTooltip(floatingMenu, editorContextMenuEnabledRef.current)
)
})
}, [view, floatingMenu])
useEffect(() => {
settingsRef.current.nonBlinkingCursor = nonBlinkingCursor
window.setTimeout(() => {