A Svelte Context Menu Library. Headless, the rendering/styling is completely in your hands. The only things the library provides are:
Escape keypressGet a taste with the demo.
Install the library with npm install --save-dev svelte-conmu
Setup one component - lets call it ContextMenu.svelte - which renders all the context menus you will have.
ContextMenuWrapper: import { ContextMenuWrapper } from "svelte-conmu";
ContextMenuWrapper will pass you the options. You will define those later on. Here it's only about the look:<div id="context-menu">
{#each options as option}
<!-- svelte-ignore a11y-click-events-have-key-events -->
{#if option.label == "hr"}
<hr />
{:else if option.action}
<div class="context-menu-option" on:click={option.action}>
{option.label}
</div>
{:else}
<div class="context-menu-info" on:click={close}>
{option.label}
</div>
{/if}
{/each}
</div>
select option, seperator & info just by evaluating the option.)Add the context menu trigger and the options to show in any component you want.
script section add this:import { contextMenu, type ContextMenuOption } from "svelte-conmu";
const contextMenuOptions: ContextMenuOption[] = [
{
label: "Do A",
action: () => {
// do A..
},
},
{ label: "hr" },
{
label: "Do B",
action: () => {
// do B...
},
},
...
];
html section add the trigger:<div on:contextmenu|preventDefault|stopPropagation={(e) =>contextMenu.toggle(e, contextMenuOptions)}>My Content</div>
Final Step. Put the ContextMenu.svelte you build in the first step into your App.svelte
<ContextMenu />
where since the positioning is absolute. Also this display (show/not-show) will be handled by the library.For full example see https://github.com/jzillmann/svelte-conmu/tree/main/example.
You can do that by extending the definition through a entry in a t.ds file, e.g. in vite-env.d.ts:
// Extend svelte-conmu with highlight option
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import * as svelte_conmu from 'svelte-conmu';
declare module 'svelte-conmu' {
export interface ContextMenuOption {
highlight?: () => boolean;
}
}
Now Type Script should give you type support for highlight when defining ContextMenuOptions and accessing them in your ContextMenu.svelte.
npm build to build the packagenpm link to make the package locally available (e.g. for the example project)cd example; npm run deploynpm publishgit tag -a $releaseVersion -m "$releaseVersion release"git push --tagspackage.jsonInspired by https://svelte.dev/repl/6fb90919e24942b2b47d9ad154386b0c?version=3.49.0.