fix(quick_edit): classic toolbar dropdowns not working

This commit is contained in:
Elian Doran 2025-11-29 12:16:42 +02:00
parent 70fe3b9773
commit ab97068a1d
No known key found for this signature in database
4 changed files with 73 additions and 58 deletions

View File

@ -59,6 +59,7 @@ body.desktop .modal.popup-editor-dialog .modal-dialog {
inset-inline-end: 0; inset-inline-end: 0;
background: var(--modal-background-color); background: var(--modal-background-color);
z-index: 998; z-index: 998;
align-items: flex-start;
} }
.modal.popup-editor-dialog .note-detail.full-height { .modal.popup-editor-dialog .note-detail.full-height {

View File

@ -18,6 +18,7 @@ import utils from "../../services/utils";
import tree from "../../services/tree"; import tree from "../../services/tree";
import froca from "../../services/froca"; import froca from "../../services/froca";
import ReadOnlyNoteInfoBar from "../ReadOnlyNoteInfoBar"; import ReadOnlyNoteInfoBar from "../ReadOnlyNoteInfoBar";
import MobileEditorToolbar from "../type_widgets/text/mobile_editor_toolbar";
export default function PopupEditor() { export default function PopupEditor() {
const [ shown, setShown ] = useState(false); const [ shown, setShown ] = useState(false);
@ -71,7 +72,11 @@ export default function PopupEditor() {
> >
<ReadOnlyNoteInfoBar /> <ReadOnlyNoteInfoBar />
<PromotedAttributes /> <PromotedAttributes />
<StandaloneRibbonAdapter component={FormattingToolbar} />
{isMobile
? <MobileEditorToolbar inPopupEditor />
: <StandaloneRibbonAdapter component={FormattingToolbar} />}
<FloatingButtons items={items} /> <FloatingButtons items={items} />
<NoteDetail /> <NoteDetail />
<NoteList media="screen" displayOnlyCollections /> <NoteList media="screen" displayOnlyCollections />

View File

@ -1,23 +1,24 @@
.classic-toolbar-outer-container { body.mobile {
.classic-toolbar-outer-container {
contain: none !important; contain: none !important;
} }
.classic-toolbar-outer-container.visible { .classic-toolbar-outer-container.visible {
height: 38px; height: 38px;
background-color: var(--main-background-color); background-color: var(--main-background-color);
position: relative; position: relative;
overflow: visible; overflow: visible;
flex-shrink: 0; flex-shrink: 0;
} }
#root-widget.virtual-keyboard-opened .classic-toolbar-outer-container.ios { #root-widget.virtual-keyboard-opened .classic-toolbar-outer-container.ios {
position: absolute; position: absolute;
inset-inline-start: 0; inset-inline-start: 0;
inset-inline-end: 0; inset-inline-end: 0;
bottom: 0; bottom: 0;
} }
.classic-toolbar-widget { .classic-toolbar-widget {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
inset-inline-start: 0; inset-inline-start: 0;
@ -28,25 +29,26 @@
align-items: flex-end; align-items: flex-end;
user-select: none; user-select: none;
scrollbar-width: 0 !important; scrollbar-width: 0 !important;
} }
.classic-toolbar-widget::-webkit-scrollbar:horizontal { .classic-toolbar-widget::-webkit-scrollbar:horizontal {
height: 0 !important; height: 0 !important;
} }
.classic-toolbar-widget.dropdown-active { .classic-toolbar-widget.dropdown-active {
height: 50vh; height: 50vh;
} }
.classic-toolbar-widget .ck.ck-toolbar { .classic-toolbar-widget .ck.ck-toolbar {
--ck-color-toolbar-background: transparent; --ck-color-toolbar-background: transparent;
--ck-color-button-default-background: transparent; --ck-color-button-default-background: transparent;
--ck-color-button-default-disabled-background: transparent; --ck-color-button-default-disabled-background: transparent;
position: absolute; position: absolute;
background-color: transparent; background-color: transparent;
border: none; border: none;
} }
.classic-toolbar-widget .ck.ck-button.ck-disabled { .classic-toolbar-widget .ck.ck-button.ck-disabled {
opacity: 0.3; opacity: 0.3;
}
} }

View File

@ -4,19 +4,23 @@ import "./mobile_editor_toolbar.css";
import { isIOS } from "../../../services/utils"; import { isIOS } from "../../../services/utils";
import { CKTextEditor, ClassicEditor } from "@triliumnext/ckeditor5"; import { CKTextEditor, ClassicEditor } from "@triliumnext/ckeditor5";
interface MobileEditorToolbarProps {
inPopupEditor?: boolean;
}
/** /**
* Handles the editing toolbar for CKEditor in mobile mode. The toolbar acts as a floating bar, with two different mechanism: * Handles the editing toolbar for CKEditor in mobile mode. The toolbar acts as a floating bar, with two different mechanism:
* *
* - On iOS, because it does not respect the viewport meta value `interactive-widget=resizes-content`, we need to listen to window resizes and scroll and reposition the toolbar using absolute positioning. * - On iOS, because it does not respect the viewport meta value `interactive-widget=resizes-content`, we need to listen to window resizes and scroll and reposition the toolbar using absolute positioning.
* - On Android, the viewport change makes the keyboard resize the content area, all we have to do is to hide the tab bar and global menu (handled in the global style). * - On Android, the viewport change makes the keyboard resize the content area, all we have to do is to hide the tab bar and global menu (handled in the global style).
*/ */
export default function MobileEditorToolbar() { export default function MobileEditorToolbar({ inPopupEditor }: MobileEditorToolbarProps) {
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
const { note, noteContext, ntxId } = useNoteContext(); const { note, noteContext, ntxId } = useNoteContext();
const [ shouldDisplay, setShouldDisplay ] = useState(false); const [ shouldDisplay, setShouldDisplay ] = useState(false);
const [ dropdownActive, setDropdownActive ] = useState(false); const [ dropdownActive, setDropdownActive ] = useState(false);
usePositioningOniOS(containerRef); usePositioningOniOS(!inPopupEditor, containerRef);
useEffect(() => { useEffect(() => {
noteContext?.isReadOnly().then(isReadOnly => { noteContext?.isReadOnly().then(isReadOnly => {
@ -29,7 +33,10 @@ export default function MobileEditorToolbar() {
if (eventNtxId !== ntxId || !containerRef.current) return; if (eventNtxId !== ntxId || !containerRef.current) return;
const toolbar = editor.ui.view.toolbar?.element; const toolbar = editor.ui.view.toolbar?.element;
if (!inPopupEditor) {
repositionDropdowns(editor); repositionDropdowns(editor);
}
if (toolbar) { if (toolbar) {
containerRef.current.replaceChildren(toolbar); containerRef.current.replaceChildren(toolbar);
} else { } else {
@ -60,7 +67,7 @@ export default function MobileEditorToolbar() {
) )
} }
function usePositioningOniOS(wrapperRef: MutableRef<HTMLDivElement | null>) { function usePositioningOniOS(enabled: boolean, wrapperRef: MutableRef<HTMLDivElement | null>) {
const adjustPosition = useCallback(() => { const adjustPosition = useCallback(() => {
if (!wrapperRef.current) return; if (!wrapperRef.current) return;
let bottom = window.innerHeight - (window.visualViewport?.height || 0); let bottom = window.innerHeight - (window.visualViewport?.height || 0);
@ -68,7 +75,7 @@ function usePositioningOniOS(wrapperRef: MutableRef<HTMLDivElement | null>) {
}, []); }, []);
useEffect(() => { useEffect(() => {
if (!isIOS()) return; if (!isIOS() || !enabled) return;
window.visualViewport?.addEventListener("resize", adjustPosition); window.visualViewport?.addEventListener("resize", adjustPosition);
window.addEventListener("scroll", adjustPosition); window.addEventListener("scroll", adjustPosition);
@ -77,7 +84,7 @@ function usePositioningOniOS(wrapperRef: MutableRef<HTMLDivElement | null>) {
window.visualViewport?.removeEventListener("resize", adjustPosition); window.visualViewport?.removeEventListener("resize", adjustPosition);
window.removeEventListener("scroll", adjustPosition); window.removeEventListener("scroll", adjustPosition);
}; };
}, []); }, [ enabled ]);
} }
/** /**