Shortcut menu instead of buttons

This commit is contained in:
Zef Hemel
2022-06-17 20:17:22 +02:00
parent 763775cdd3
commit 5fe10e441b
10 changed files with 202 additions and 137 deletions
+45 -15
View File
@@ -1,4 +1,5 @@
import { ActionButton, Notification } from "../types";
import { useEffect, useState } from "react";
import { ShortcutItem, Notification } from "../types";
function prettyName(s: string | undefined): string {
if (!s) {
@@ -11,7 +12,7 @@ export function TopBar({
pageName,
unsavedChanges,
notifications,
actionButtons,
shortcutItems,
onClick,
lhs,
rhs,
@@ -19,11 +20,25 @@ export function TopBar({
pageName?: string;
unsavedChanges: boolean;
notifications: Notification[];
actionButtons: ActionButton[];
shortcutItems: ShortcutItem[];
onClick: () => void;
lhs?: React.ReactNode;
rhs?: React.ReactNode;
}) {
const [menuExpanded, setMenuExpanded] = useState(false);
useEffect(() => {
function closer() {
setMenuExpanded(false);
}
document.addEventListener("click", closer);
return () => {
document.removeEventListener("click", closer);
};
}, []);
return (
<div id="top" onClick={onClick}>
{lhs}
@@ -42,18 +57,33 @@ export function TopBar({
</div>
)}
<div className="actions">
{actionButtons.map((actionButton, idx) => (
<button
key={idx}
onClick={(e) => {
e.stopPropagation();
actionButton.run();
}}
title={actionButton.tooltip}
>
{actionButton.label}
</button>
))}
<button
onClick={(e) => {
setMenuExpanded(!menuExpanded);
e.stopPropagation();
}}
>
...
</button>
{menuExpanded && (
<ul>
{shortcutItems.map((actionButton, idx) => (
<li key={idx}>
<a
href="#"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
setMenuExpanded(false);
actionButton.run();
}}
>
{actionButton.label}
</a>
</li>
))}
</ul>
)}
</div>
</div>
</div>
+5 -5
View File
@@ -127,11 +127,11 @@ export class Editor {
// Command hook
this.commandHook = new CommandHook();
this.commandHook.on({
commandsUpdated: (commandMap, actionButtons) => {
commandsUpdated: (commandMap, shortcutItems) => {
this.viewDispatch({
type: "update-commands",
commands: commandMap,
actionButtons: actionButtons,
shortcutItems: shortcutItems,
});
},
});
@@ -669,15 +669,15 @@ export class Editor {
pageName={viewState.currentPage}
notifications={viewState.notifications}
unsavedChanges={viewState.unsavedChanges}
actionButtons={[
shortcutItems={[
{
label: "⚡️",
label: "Run command",
orderId: 0,
run: () => {
this.viewDispatch({ type: "show-palette" });
},
},
...viewState.actionButtons,
...viewState.shortcutItems,
]}
onClick={() => {
dispatch({ type: "start-navigate" });
+11 -13
View File
@@ -1,7 +1,7 @@
import { Hook, Manifest } from "@plugos/plugos/types";
import { System } from "@plugos/plugos/system";
import { EventEmitter } from "@plugos/plugos/event";
import { ActionButton } from "../types";
import { ShortcutItem } from "../types";
export type CommandDef = {
name: string;
@@ -12,13 +12,12 @@ export type CommandDef = {
key?: string;
mac?: string;
// Action button
button?: ButtonDef;
// Shortcuts in UI
shortcut?: ShortcutDef;
};
export type ButtonDef = {
export type ShortcutDef = {
label: string;
tooltip?: string;
};
export type AppCommand = {
@@ -33,7 +32,7 @@ export type CommandHookT = {
export type CommandHookEvents = {
commandsUpdated(
commandMap: Map<string, AppCommand>,
appButtons: ActionButton[]
appButtons: ShortcutItem[]
): void;
};
@@ -42,11 +41,11 @@ export class CommandHook
implements Hook<CommandHookT>
{
editorCommands = new Map<string, AppCommand>();
actionButtons: ActionButton[] = [];
shortcutItems: ShortcutItem[] = [];
buildAllCommands(system: System<CommandHookT>) {
this.editorCommands.clear();
this.actionButtons = [];
this.shortcutItems = [];
for (let plug of system.loadedPlugs.values()) {
for (const [name, functionDef] of Object.entries(
plug.manifest!.functions
@@ -61,10 +60,9 @@ export class CommandHook
return plug.invoke(name, []);
},
});
if (cmd.button) {
this.actionButtons.push({
label: cmd.button.label,
tooltip: cmd.button.tooltip,
if (cmd.shortcut) {
this.shortcutItems.push({
label: cmd.shortcut.label,
run: () => {
return plug.invoke(name, []);
},
@@ -72,7 +70,7 @@ export class CommandHook
}
}
}
this.emit("commandsUpdated", this.editorCommands, this.actionButtons);
this.emit("commandsUpdated", this.editorCommands, this.shortcutItems);
}
apply(system: System<CommandHookT>): void {
+1 -1
View File
@@ -76,7 +76,7 @@ export default function reducer(
return {
...state,
commands: action.commands,
actionButtons: action.actionButtons,
shortcutItems: action.shortcutItems,
};
case "show-notification":
return {
+42 -9
View File
@@ -58,12 +58,12 @@ body {
#top {
display: flex;
flex-direction: row;
z-index: 20;
height: $top-bar-height;
background-color: rgb(213, 213, 213);
border-bottom: rgb(193, 193, 193) 1px solid;
color: rgb(55, 55, 55);
.main {
flex: 2;
@@ -73,6 +73,10 @@ body {
font-size: 28px;
padding: 10px 20px;
@media (max-width: $max-editor-width) {
width: 800px;
}
.status {
position: absolute;
font-family: "iA-Mono";
@@ -90,6 +94,14 @@ body {
.current-page {
font-family: var(--ui-font);
font-weight: bold;
overflow: hidden;
white-space: nowrap;
margin-right: 40px;
display: block;
text-overflow: ellipsis;
direction: rtl;
text-align: left;
}
.icon {
@@ -107,15 +119,36 @@ body {
}
.actions {
float: right;
text-align: right;
margin-top: -35px;
button {
border: 0;
// border-radius: 5px;
// background-color: rgba(77,141,255,0.07);
background-color: transparent;
padding: 3px;
font-family: "IA-Mono", "Menlo";
font-size: 80%;
ul {
list-style: none;
margin-left: 0;
padding-left: 0;
margin-top: 0;
list-style: none;
background: #fff;
border: #000 1px solid;
text-align: left;
a {
padding: 3px;
font-family: var(--ui-font);
font-size: 50%;
text-decoration: none;
color: #000;
}
li {
padding-left: 10px;
padding-right: 10px;
padding-bottom: 5px;
}
li:hover {
background-color: #4d8dff12;
}
}
}
}
+4 -5
View File
@@ -9,9 +9,8 @@ export type Notification = {
date: Date;
};
export type ActionButton = {
export type ShortcutItem = {
label: string;
tooltip?: string;
orderId?: number;
run: () => void;
};
@@ -35,7 +34,7 @@ export type AppViewState = {
allPages: Set<PageMeta>;
commands: Map<string, AppCommand>;
notifications: Notification[];
actionButtons: ActionButton[];
shortcutItems: ShortcutItem[];
recentCommands: Map<string, Date>;
showFilterBox: boolean;
@@ -61,7 +60,7 @@ export const initialViewState: AppViewState = {
commands: new Map(),
recentCommands: new Map(),
notifications: [],
actionButtons: [],
shortcutItems: [],
showFilterBox: false,
filterBoxHelpText: "",
filterBoxLabel: "",
@@ -80,7 +79,7 @@ export type Action =
| {
type: "update-commands";
commands: Map<string, AppCommand>;
actionButtons: ActionButton[];
shortcutItems: ShortcutItem[];
}
| { type: "show-palette"; context?: string }
| { type: "hide-palette" }