Skip to content

Commit

Permalink
Menu.svelte, MenuBar.svelte to svelte 5
Browse files Browse the repository at this point in the history
  • Loading branch information
kjk committed Jun 6, 2024
1 parent b96d98d commit 6422b6d
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 58 deletions.
40 changes: 22 additions & 18 deletions frontend/src/Menu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,22 @@
</script>

<script>
import { createEventDispatcher } from "svelte";
import { parseShortcut, serializeShortuct } from "./keys.js";
import { len, splitMax } from "./util.js";
const dispatch = createEventDispatcher();
// based on https://play.tailwindcss.com/0xQBSdXxsK
export let menu; // array of menu items
// menu nesting needed to style child based on parent
/** @type {{
menu: any[], // array of menu items
nest: number,
filterFn: Function,
onmenucmd: (cmd: string, ev: Event) => void,
}}*/
let { menu, nest = 1, filterFn, onmenucmd } = $props();
// nest: menu nesting needed to style child based on parent
// see menu-parent1, menu-parent2, menu-parent3,
// menu-child1, menu-child2, menu-child3 global classes
export let nest = 1;
export let filterFn;
function sanitizeShortcut(txt) {
const s = parseShortcut(txt);
Expand Down Expand Up @@ -125,15 +126,16 @@
console.log("Menu.svelte: menuClicked: no data-menu-id on:", el);
return;
}
dispatch("menucmd", { cmd: cmdId });
onmenucmd(cmdId, null);
}
</script>

<!-- svelte-ignore a11y-click-events-have-key-events a11y-interactive-supports-focus -->
<!-- svelte-ignore a11y_click_events_have_key_events -->
<div
role="menu"
tabindex="-1"
class="mt-1 rounded-md border border-neutral-50 bg-white py-1 shadow-lg"
on:click={handleClicked}
onclick={handleClicked}
>
{#each menu as mi}
{@const isDiv = mi === menuSep || mi[0] === menuSep}
Expand All @@ -147,13 +149,14 @@
{#if isDiv}
<div class="border-y border-gray-200 mt-1 mb-1"></div>
{:else if isSubmenu}
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<!-- svelte-ignore a11y_mouse_events_have_key_events -->
<div
role="menuitem"
tabindex="-1"
class="menu-parent{nest} relative my-1"
on:mouseleave={handleMouseLeave}
on:mouseover={handleMouseOver}
on:mouseenter={handleMouseEnter}
onmouseleave={handleMouseLeave}
onmouseover={handleMouseOver}
onmouseenter={handleMouseEnter}
>
<button
class="flex w-full items-center justify-between pl-3 pr-2 py-0.5"
Expand Down Expand Up @@ -184,13 +187,14 @@
</div>
</div>
{:else}
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<!-- svelte-ignore a11y_mouse_events_have_key_events -->
<div
role="menuitem"
tabindex="-1"
data-cmd-id={cmdId}
class="min-w-[18em] flex items-center justify-between px-3 py-1 whitespace-nowrap"
on:mouseleave={handleMouseLeave}
on:mouseover={handleMouseOver}
onmouseleave={handleMouseLeave}
onmouseover={handleMouseOver}
>
<span class="flex items-center">
<svg
Expand Down
37 changes: 25 additions & 12 deletions frontend/src/MenuBar.svelte
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
<script>
// menu based on https://play.tailwindcss.com/0xQBSdXxsK
import Menu, { fixMenuName } from "./Menu.svelte";
import { onMount, createEventDispatcher } from "svelte";
import { len, splitMax } from "./util";
import { parseShortcut } from "./keys";
let debugKeys = false;
const dispatch = createEventDispatcher();
/*
export let menuBar; // definition of the menubar
export let noMenuCommands = null; // for commands that have shortcuts but no menu
/** @type {Function} */
export let filterFn = null;
export let hidden = false;
// function called when menu has been opened
// allows the owner to modify the menu by changing DOM
/** @type {Function} */
export let menuDidOpenFn = null;
*/
/** @type { {
menuBar: any,
noMenuCommands: any,
filterFn: Function,
hidden: boolean,
menuDidOpenFn: Function,
onmenucmd: (cmd: string, ev: Event) => void,
} } */
let {
menuBar,
noMenuCommands = null,
filterFn = null,
hidden = false,
menuDidOpenFn = null,
onmenucmd,
} = $props();
/** @type {HTMLElement} */
let menuBarElement = null;
let menuBarElement = $state(null);
/** @type {import("./keys").Shortcut[]} */
let keyboardShortcuts = [];
Expand Down Expand Up @@ -153,11 +167,11 @@
console.log("handleKeyDown:", ks);
}
// handler is responsible for stopping propagation of the event
dispatch("menucmd", { ev: ev, cmd: ks.cmdId });
onmenucmd(ks.cmdId, ev);
}
}
onMount(() => {
$effect(() => {
document.addEventListener("keydown", handleKeyDown);
return () => {
document.removeEventListener("keydown", handleKeyDown);
Expand All @@ -174,17 +188,16 @@
{#each menuBar as mi}
{@const title = mi[0]}
{@const menu = mi[1]}
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<div class="parent relative" tabindex="-1" role="menubar">
<button
class="rounded-md px-3 py-1 hover:bg-black/5 menu-trigger"
on:mouseover={handleMouseOver}
on:focus={handleFocus}>{fixMenuName(title)}</button
onmouseover={handleMouseOver}
onfocus={handleFocus}>{fixMenuName(title)}</button
>
<div
class="child invisible absolute top-0 transform opacity-0 transition-all duration-100"
>
<Menu {filterFn} on:menucmd {menu} />
<Menu nest={1} {filterFn} {onmenucmd} {menu} />
</div>
</div>
{/each}
Expand Down
17 changes: 0 additions & 17 deletions frontend/src/Test.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
<script>
import Spinners from "./Spinners.svelte";
import MenuBar from "./MenuBar.svelte";
import { mainMenuBar } from "./notepad2/menu-notepad2.js";
function handleMenuCmd(cmd) {
// console.log("handleMenuCmd:", cmd.detail);
let el = document.activeElement;
if (el) {
// console.log("active element:", el);
/** @type {HTMLElement}*/ (el).blur();
}
}
</script>

<div class="mb-4">
Expand Down Expand Up @@ -52,9 +41,3 @@
<div>Spinners classic-fadein</div>
<Spinners kind="classic-fadein" />
</details>

<details open>
<summary>Menu test</summary>
<!-- svelte-ignore a11y-invalid-attribute -->
<MenuBar menuBar={mainMenuBar} on:menucmd={handleMenuCmd} />
</details>
16 changes: 5 additions & 11 deletions frontend/src/notepad2/Notepad2.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -1072,12 +1072,7 @@
const cmdId = await dialog;
console.log("cmdViewScheme:", cmdId);
if (cmdId) {
const arg = {
detail: {
cmd: cmdId,
},
};
handleMenuCmd(arg);
handleMenuCmd(cmdId, null);
}
}
Expand All @@ -1101,9 +1096,7 @@
// this can be invoked via keyboard shortcut of via menu
// if via keyboard, arg.detail.ev is set
// TODO: if via menu, we need to be smart about closeMen() vs. closeMenuAndFocusEditor()
async function handleMenuCmd(arg) {
const cmdId = arg.detail.cmd;
const ev = arg.detail.ev;
async function handleMenuCmd(cmdId, ev) {
let s = "";
let stopPropagation = true;
const fromMenu = !ev;
Expand Down Expand Up @@ -1904,11 +1897,12 @@
</svg></a
>
<MenuBar
hidden={false}
filterFn={filterMenuItem}
menuDidOpenFn={handleMenuDidOpen}
menuBar={m.mainMenuBar}
noMenuCommands={m.noMenuCommands}
on:menucmd={handleMenuCmd}
onmenucmd={handleMenuCmd}
/>
<div
class="truncate border-l border-gray-500 font-semibold text-gray-900 pl-2"
Expand Down Expand Up @@ -1947,7 +1941,7 @@
menuDidOpenFn={handleMenuDidOpen}
menuBar={m.mainMenuBar}
noMenuCommands={m.noMenuCommands}
on:menucmd={handleMenuCmd}
onmenucmd={handleMenuCmd}
/>
<div class="absolute flex top-[2px] right-[4px] text-sm">
<div class="py-0.5 truncate font-semibold text-gray-900 border-l">
Expand Down

0 comments on commit 6422b6d

Please sign in to comment.