chore(client/ts): port abstract_button, command_button, onclick_button

This commit is contained in:
Elian Doran 2025-01-07 11:26:49 +02:00
parent 6905e1536e
commit f3a18a9942
No known key found for this signature in database
6 changed files with 99 additions and 67 deletions

View File

@ -6,7 +6,7 @@ import Component from "../components/component.js";
const keyboardActionRepo: Record<string, Action> = {};
// TODO: Deduplicate with server.
interface Action {
export interface Action {
actionName: CommandNames;
effectiveShortcuts: string[];
scope: string;

View File

@ -5,36 +5,25 @@ const TPL = `<button class="button-widget bx"
title=""></button>`;
type TitlePlacement = "top" | "bottom" | "left" | "right";
type StringOrCallback = (() => string);
type StringOrCallback = string | (() => string);
type ContextMenuHandler = (e: JQuery.ContextMenuEvent<any, any, any, any> | null) => void;
interface Settings {
export interface AbstractButtonWidgetSettings {
titlePlacement: TitlePlacement;
title: string | StringOrCallback | null;
icon: string | StringOrCallback | null;
title: StringOrCallback | null;
icon: StringOrCallback | null;
onContextMenu: ContextMenuHandler | null;
}
export default class AbstractButtonWidget extends NoteContextAwareWidget {
export default class AbstractButtonWidget<SettingsT extends AbstractButtonWidgetSettings> extends NoteContextAwareWidget {
private settings: Settings;
private tooltip!: bootstrap.Tooltip;
protected settings!: SettingsT;
protected tooltip!: bootstrap.Tooltip;
isEnabled() {
return true;
}
constructor() {
super();
this.settings = {
titlePlacement: 'right',
title: null,
icon: null,
onContextMenu: null
};
}
doRender() {
this.$widget = $(TPL);
// Fix once bootstrap is available as non-UMD

View File

@ -1,11 +1,32 @@
import keyboardActionsService from "../../services/keyboard_actions.js";
import AbstractButtonWidget from "./abstract_button.js";
import { CommandNames } from "../../components/app_context.js";
import keyboardActionsService, { Action } from "../../services/keyboard_actions.js";
import AbstractButtonWidget, { AbstractButtonWidgetSettings } from "./abstract_button.js";
let actions;
let actions: Action[];
keyboardActionsService.getActions().then(as => actions = as);
export default class CommandButtonWidget extends AbstractButtonWidget {
// TODO: Is this actually used?
export type ClickHandler = (widget: CommandButtonWidget, e: JQuery.ClickEvent<any, any, any, any>) => void;
type CommandOrCallback = (CommandNames | (() => CommandNames));
interface CommandButtonWidgetSettings extends AbstractButtonWidgetSettings {
command?: CommandOrCallback;
onClick?: ClickHandler;
}
export default class CommandButtonWidget extends AbstractButtonWidget<CommandButtonWidgetSettings> {
constructor() {
super();
this.settings = {
titlePlacement: 'right',
title: null,
icon: null,
onContextMenu: null
};
}
doRender() {
super.doRender();
@ -13,7 +34,9 @@ export default class CommandButtonWidget extends AbstractButtonWidget {
this.$widget.on("click", () => {
this.tooltip.hide();
this.triggerCommand(this._command);
if (this._command) {
this.triggerCommand(this._command);
}
});
} else {
console.warn(`Button widget '${this.componentId}' has no defined command`, this.settings);
@ -32,16 +55,12 @@ export default class CommandButtonWidget extends AbstractButtonWidget {
}
}
onClick(handler) {
onClick(handler: ClickHandler) {
this.settings.onClick = handler;
return this;
}
/**
* @param {function|string} command
* @returns {this}
*/
command(command) {
command(command: CommandOrCallback) {
this.settings.command = command;
return this;
}

View File

@ -1,36 +0,0 @@
import AbstractButtonWidget from "./abstract_button.js";
import { t } from "../../services/i18n.js";
export default class OnClickButtonWidget extends AbstractButtonWidget {
doRender() {
super.doRender();
if (this.settings.onClick) {
this.$widget.on("click", e => {
this.$widget.tooltip("hide");
this.settings.onClick(this, e);
});
} else {
console.warn(t("onclick_button.no_click_handler", { componentId: this.componentId }), this.settings);
}
if (this.settings.onAuxClick) {
this.$widget.on("auxclick", e => {
this.$widget.tooltip("hide");
this.settings.onAuxClick(this, e);
});
}
}
onClick(handler) {
this.settings.onClick = handler;
return this;
}
onAuxClick(handler) {
this.settings.onAuxClick = handler;
return this;
}
}

View File

@ -0,0 +1,59 @@
import AbstractButtonWidget, { AbstractButtonWidgetSettings, type AuxClickHandler, type ClickHandler } from "./abstract_button.js";
import { t } from "../../services/i18n.js";
export type ClickHandler = (widget: OnClickButtonWidget, e: JQuery.ClickEvent<any, any, any, any>) => void;
export type AuxClickHandler = (widget: OnClickButtonWidget, e: JQuery.TriggeredEvent<any, any, any, any>) => void;
interface OnClickButtonWidgetSettings extends AbstractButtonWidgetSettings {
onClick?: ClickHandler;
onAuxClick?: AuxClickHandler;
}
export default class OnClickButtonWidget extends AbstractButtonWidget<OnClickButtonWidgetSettings> {
constructor() {
super();
this.settings = {
titlePlacement: 'right',
title: null,
icon: null,
onContextMenu: null
};
}
doRender() {
super.doRender();
if (this.settings.onClick) {
this.$widget.on("click", e => {
this.$widget.tooltip("hide");
if (this.settings.onClick) {
this.settings.onClick(this, e);
}
});
} else {
console.warn(t("onclick_button.no_click_handler", { componentId: this.componentId }), this.settings);
}
if (this.settings.onAuxClick) {
this.$widget.on("auxclick", e => {
this.$widget.tooltip("hide");
if (this.settings.onAuxClick) {
this.settings.onAuxClick(this, e);
}
});
}
}
onClick(handler: ClickHandler) {
this.settings.onClick = handler;
return this;
}
onAuxClick(handler: AuxClickHandler) {
this.settings.onAuxClick = handler;
return this;
}
}

View File

@ -1,4 +1,5 @@
import BasicWidget from "./basic_widget.js";
import AbstractButtonWidget from "./buttons/abstract_button.js";
import NoteContextAwareWidget from "./note_context_aware_widget.js";
const WIDGET_TPL = `
@ -26,7 +27,7 @@ class RightPanelWidget extends NoteContextAwareWidget {
/** Title to show in the panel. */
get widgetTitle() { return "Untitled widget"; }
get widgetButtons() { return []; }
get widgetButtons(): AbstractButtonWidget<any>[] { return []; }
get help() { return {}; }