feat(note_actions): group development options

This commit is contained in:
Elian Doran 2025-12-10 16:51:07 +02:00
parent 2060bb8cdd
commit 7c5df21685
No known key found for this signature in database
4 changed files with 59 additions and 29 deletions

View File

@ -1321,6 +1321,11 @@ body.desktop li.dropdown-submenu:hover > ul.dropdown-menu {
overflow: auto; overflow: auto;
} }
.dropdown-submenu.dropstart > .dropdown-menu {
inset-inline-start: auto;
inset-inline-end: calc(100% - 2px);
}
body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu { body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
inset-inline-start: calc(-100% + 10px); inset-inline-start: calc(-100% + 10px);
} }

View File

@ -176,6 +176,11 @@ body.desktop .dropdown-submenu .dropdown-menu {
cursor: default !important; cursor: default !important;
} }
.dropdown-menu:has(> .dropdown-submenu.dropstart) > .dropdown-item {
padding-inline-end: var(--menu-item-start-padding) !important;
padding-inline-start: var(--menu-item-end-padding) !important;
}
:root .dropdown-item:focus-visible { :root .dropdown-item:focus-visible {
outline: 2px solid var(--input-focus-outline-color) !important; outline: 2px solid var(--input-focus-outline-color) !important;
background-color: transparent; background-color: transparent;
@ -249,7 +254,7 @@ html body .dropdown-item[disabled] {
} }
/* Menu item arrow */ /* Menu item arrow */
.dropdown-menu .dropdown-toggle::after { .dropdown-submenu:not(.dropstart) .dropdown-toggle::after {
content: "\ed3b" !important; content: "\ed3b" !important;
position: absolute; position: absolute;
display: flex !important; display: flex !important;
@ -265,6 +270,22 @@ html body .dropdown-item[disabled] {
color: var(--menu-item-arrow-color) !important; color: var(--menu-item-arrow-color) !important;
} }
.dropdown-submenu.dropstart .dropdown-toggle::before {
content: "\ea4d" !important;
position: absolute;
display: flex !important;
align-items: center;
justify-content: center;
top: 0;
inset-inline-start: 0;
margin: unset !important;
border: unset !important;
padding: 0 4px;
font-family: boxicons;
font-size: 1.2em;
color: var(--menu-item-arrow-color) !important;
}
body[dir=rtl] .dropdown-menu:not([data-popper-placement="bottom-start"]) .dropdown-toggle::after { body[dir=rtl] .dropdown-menu:not([data-popper-placement="bottom-start"]) .dropdown-toggle::after {
content: "\ea4d" !important; content: "\ea4d" !important;
} }

View File

@ -161,11 +161,16 @@ export function FormDropdownDivider() {
return <div className="dropdown-divider" />; return <div className="dropdown-divider" />;
} }
export function FormDropdownSubmenu({ icon, title, children }: { icon: string, title: ComponentChildren, children: ComponentChildren }) { export function FormDropdownSubmenu({ icon, title, children, dropStart }: {
icon: string,
title: ComponentChildren,
children: ComponentChildren,
dropStart?: boolean
}) {
const [ openOnMobile, setOpenOnMobile ] = useState(false); const [ openOnMobile, setOpenOnMobile ] = useState(false);
return ( return (
<li className={`dropdown-item dropdown-submenu ${openOnMobile ? "submenu-open" : ""}`}> <li className={clsx("dropdown-item dropdown-submenu", { "submenu-open": openOnMobile, "dropstart": dropStart })}>
<span <span
className="dropdown-toggle" className="dropdown-toggle"
onClick={(e) => { onClick={(e) => {
@ -184,5 +189,5 @@ export function FormDropdownSubmenu({ icon, title, children }: { icon: string, t
{children} {children}
</ul> </ul>
</li> </li>
) );
} }

View File

@ -13,7 +13,7 @@ import { isElectron as getIsElectron, isMac as getIsMac } from "../../services/u
import ws from "../../services/ws"; import ws from "../../services/ws";
import ActionButton from "../react/ActionButton"; import ActionButton from "../react/ActionButton";
import Dropdown from "../react/Dropdown"; import Dropdown from "../react/Dropdown";
import { FormDropdownDivider, FormListHeader, FormListItem } from "../react/FormList"; import { FormDropdownDivider, FormDropdownSubmenu, FormListItem } from "../react/FormList";
import { useIsNoteReadOnly, useNoteContext, useNoteLabel, useNoteProperty, useTriliumOption } from "../react/hooks"; import { useIsNoteReadOnly, useNoteContext, useNoteLabel, useNoteProperty, useTriliumOption } from "../react/hooks";
import { ParentComponent } from "../react/react_utils"; import { ParentComponent } from "../react/react_utils";
import { isExperimentalFeatureEnabled } from "../../services/experimental_features"; import { isExperimentalFeatureEnabled } from "../../services/experimental_features";
@ -114,23 +114,22 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
function DevelopmentActions({ note, noteContext }: { note: FNote, noteContext?: NoteContext }) { function DevelopmentActions({ note, noteContext }: { note: FNote, noteContext?: NoteContext }) {
return ( return (
<> <FormDropdownSubmenu title="Development Actions" icon="bx bx-wrench" dropStart>
<FormListHeader text="Development-only Actions" />
<FormListItem <FormListItem
icon="bx bx-printer" icon="bx bx-printer"
onClick={() => window.open(`/?print=#root/${note.noteId}`, "_blank")} onClick={() => window.open(`/?print=#root/${note.noteId}`, "_blank")}
>Open print page</FormListItem> >Open print page</FormListItem>
{note.type === "text" && ( <FormListItem
<FormListItem icon="bx bx-error"
icon="bx bx-error" disabled={note.type !== "text"}
onClick={() => { onClick={() => {
noteContext?.getTextEditor(editor => { noteContext?.getTextEditor(editor => {
editor.editing.view.change(() => { editor.editing.view.change(() => {
throw new Error("Editor crashed."); throw new Error("Editor crashed.");
});
}); });
}}>Crash editor</FormListItem>)} });
</> }}>Crash editor</FormListItem>
</FormDropdownSubmenu>
); );
} }