Button goes here.
;
+}
diff --git a/apps/client/src/widgets/launch_bar/SpacerWidget.tsx b/apps/client/src/widgets/launch_bar/SpacerWidget.tsx
new file mode 100644
index 000000000..5f89369c2
--- /dev/null
+++ b/apps/client/src/widgets/launch_bar/SpacerWidget.tsx
@@ -0,0 +1,35 @@
+import appContext, { CommandNames } from "../../components/app_context";
+import contextMenu from "../../menus/context_menu";
+import { t } from "../../services/i18n";
+import { isMobile } from "../../services/utils";
+
+interface SpacerWidgetProps {
+ baseSize?: number;
+ growthFactor?: number;
+}
+
+export default function SpacerWidget({ baseSize, growthFactor }: SpacerWidgetProps) {
+ return (
+ {
+ e.preventDefault();
+ contextMenu.show
({
+ x: e.pageX,
+ y: e.pageY,
+ items: [{ title: t("spacer.configure_launchbar"), command: "showLaunchBarSubtree", uiIcon: "bx " + (isMobile() ? "bx-mobile" : "bx-sidebar") }],
+ selectMenuItemHandler: ({ command }) => {
+ if (command) {
+ appContext.triggerCommand(command);
+ }
+ }
+ });
+ }}
+ />
+ )
+}
diff --git a/apps/client/src/widgets/launch_bar/launch_bar_widgets.tsx b/apps/client/src/widgets/launch_bar/launch_bar_widgets.tsx
new file mode 100644
index 000000000..1ea64a852
--- /dev/null
+++ b/apps/client/src/widgets/launch_bar/launch_bar_widgets.tsx
@@ -0,0 +1,30 @@
+import ActionButton, { ActionButtonProps } from "../react/ActionButton";
+import Dropdown, { DropdownProps } from "../react/Dropdown";
+import Icon from "../react/Icon";
+
+export interface LaunchBarWidgetProps {
+ isHorizontalLayout: boolean;
+}
+
+export function LaunchBarActionButton(props: Omit) {
+ return (
+
+ )
+}
+
+export function LaunchBarDropdownButton({ children, icon, ...props }: Pick & { icon: string }) {
+ return (
+ }
+ {...props}
+ >{children}
+ )
+}
diff --git a/apps/client/src/widgets/react/ActionButton.tsx b/apps/client/src/widgets/react/ActionButton.tsx
index 28489005d..a37f34514 100644
--- a/apps/client/src/widgets/react/ActionButton.tsx
+++ b/apps/client/src/widgets/react/ActionButton.tsx
@@ -2,13 +2,13 @@ import { useEffect, useRef, useState } from "preact/hooks";
import { CommandNames } from "../../components/app_context";
import { useStaticTooltip } from "./hooks";
import keyboard_actions from "../../services/keyboard_actions";
+import { HTMLAttributes } from "preact";
-export interface ActionButtonProps {
+export interface ActionButtonProps extends Pick, "onClick" | "onAuxClick" | "onContextMenu"> {
text: string;
titlePosition?: "top" | "right" | "bottom" | "left";
icon: string;
className?: string;
- onClick?: (e: MouseEvent) => void;
triggerCommand?: CommandNames;
noIconActionClass?: boolean;
frame?: boolean;
@@ -16,7 +16,7 @@ export interface ActionButtonProps {
disabled?: boolean;
}
-export default function ActionButton({ text, icon, className, onClick, triggerCommand, titlePosition, noIconActionClass, frame, active, disabled }: ActionButtonProps) {
+export default function ActionButton({ text, icon, className, triggerCommand, titlePosition, noIconActionClass, frame, active, disabled, ...restProps }: ActionButtonProps) {
const buttonRef = useRef(null);
const [ keyboardShortcut, setKeyboardShortcut ] = useState();
@@ -35,8 +35,8 @@ export default function ActionButton({ text, icon, className, onClick, triggerCo
return ;
}
diff --git a/apps/client/src/widgets/react/NoteLink.tsx b/apps/client/src/widgets/react/NoteLink.tsx
index 758122ed0..c8bcc5065 100644
--- a/apps/client/src/widgets/react/NoteLink.tsx
+++ b/apps/client/src/widgets/react/NoteLink.tsx
@@ -4,6 +4,7 @@ import { useImperativeSearchHighlighlighting, useTriliumEvent } from "./hooks";
interface NoteLinkOpts {
className?: string;
+ containerClassName?: string;
notePath: string | string[];
showNotePath?: boolean;
showNoteIcon?: boolean;
@@ -17,7 +18,7 @@ interface NoteLinkOpts {
noContextMenu?: boolean;
}
-export default function NoteLink({ className, notePath, showNotePath, showNoteIcon, style, noPreview, noTnLink, highlightedTokens, title, viewScope, noContextMenu }: NoteLinkOpts) {
+export default function NoteLink({ className, containerClassName, notePath, showNotePath, showNoteIcon, style, noPreview, noTnLink, highlightedTokens, title, viewScope, noContextMenu }: NoteLinkOpts) {
const stringifiedNotePath = Array.isArray(notePath) ? notePath.join("/") : notePath;
const noteId = stringifiedNotePath.split("/").at(-1);
const ref = useRef(null);
@@ -71,6 +72,6 @@ export default function NoteLink({ className, notePath, showNotePath, showNoteIc
$linkEl?.addClass(className);
}
- return
+ return
}
diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx
index b14e079e7..c602802d5 100644
--- a/apps/client/src/widgets/react/hooks.tsx
+++ b/apps/client/src/widgets/react/hooks.tsx
@@ -23,6 +23,7 @@ import toast, { ToastOptions } from "../../services/toast";
import utils, { escapeRegExp, reloadFrontendApp } from "../../services/utils";
import server from "../../services/server";
import { removeIndividualBinding } from "../../services/shortcuts";
+import froca from "../../services/froca";
export function useTriliumEvent(eventName: T, handler: (data: EventData) => void) {
const parentComponent = useContext(ParentComponent);
@@ -836,3 +837,15 @@ async function isNoteReadOnly(note: FNote, noteContext: NoteContext) {
return true;
}
+
+export function useChildNotes(parentNoteId: string) {
+ const [ childNotes, setChildNotes ] = useState([]);
+ async function refreshChildNotes() {
+ const parentNote = await froca.getNote(parentNoteId);
+ const childNotes = await parentNote?.getChildNotes();
+ setChildNotes(childNotes ?? []);
+ }
+ useEffect(() => { refreshChildNotes() }, [ parentNoteId ]);
+
+ return childNotes;
+}
diff --git a/apps/client/src/widgets/spacer.ts b/apps/client/src/widgets/spacer.ts
deleted file mode 100644
index bb50e90d2..000000000
--- a/apps/client/src/widgets/spacer.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { t } from "../services/i18n.js";
-import BasicWidget from "./basic_widget.js";
-import contextMenu from "../menus/context_menu.js";
-import appContext, { type CommandNames } from "../components/app_context.js";
-import utils from "../services/utils.js";
-
-const TPL = /*html*/``;
-
-export default class SpacerWidget extends BasicWidget {
- private baseSize: number;
- private growthFactor: number;
-
- constructor(baseSize = 0, growthFactor = 1000) {
- super();
-
- this.baseSize = baseSize;
- this.growthFactor = growthFactor;
- }
-
- doRender() {
- this.$widget = $(TPL);
- this.$widget.css("flex-basis", this.baseSize);
- this.$widget.css("flex-grow", this.growthFactor);
- this.$widget.css("flex-shrink", 1000);
-
- this.$widget.on("contextmenu", (e) => {
- this.$widget.tooltip("hide");
-
- contextMenu.show({
- x: e.pageX,
- y: e.pageY,
- items: [{ title: t("spacer.configure_launchbar"), command: "showLaunchBarSubtree", uiIcon: "bx " + (utils.isMobile() ? "bx-mobile" : "bx-sidebar") }],
- selectMenuItemHandler: ({ command }) => {
- if (command) {
- appContext.triggerCommand(command);
- }
- }
- });
-
- return false; // blocks default browser right click menu
- });
- }
-}
diff --git a/packages/commons/src/lib/attribute_names.ts b/packages/commons/src/lib/attribute_names.ts
index 767f05872..8b3ec3f37 100644
--- a/packages/commons/src/lib/attribute_names.ts
+++ b/packages/commons/src/lib/attribute_names.ts
@@ -24,6 +24,9 @@ type Labels = {
orderBy: string;
orderDirection: string;
+ // Launch bar
+ bookmarkFolder: boolean;
+
// Collection-specific
viewType: string;
status: string;