finally back up and running again
This commit is contained in:
parent
529647b0d7
commit
4a5f0cf2d1
8 changed files with 101 additions and 41 deletions
|
@ -1,4 +1,4 @@
|
|||
import { Accessor, Component, createContext, createEffect, createMemo, createSignal, createUniqueId, For, JSX, ParentComponent, splitProps, useContext } from "solid-js";
|
||||
import { Accessor, Component, createContext, createEffect, createMemo, createSignal, For, JSX, ParentComponent, splitProps, useContext } from "solid-js";
|
||||
import { CommandType } from "./index";
|
||||
import css from "./contextMenu.module.css";
|
||||
|
||||
|
@ -62,11 +62,11 @@ const Menu: Component<{ children: (command: CommandType) => JSX.Element }> = (pr
|
|||
command();
|
||||
};
|
||||
|
||||
return <ul ref={setRoot} class={css.menu} style={`position-anchor: ${context.target()?.style.getPropertyValue('anchor-name')};`} popover ontoggle={onToggle}>
|
||||
return <menu ref={setRoot} class={css.menu} style={`position-anchor: ${context.target()?.style.getPropertyValue('anchor-name')};`} popover ontoggle={onToggle}>
|
||||
<For each={context.commands()}>{
|
||||
command => <li onpointerdown={onCommand(command)}>{props.children(command)}</li>
|
||||
}</For>
|
||||
</ul>;
|
||||
</menu>;
|
||||
};
|
||||
|
||||
const Handle: ParentComponent<Record<string, any>> = (props) => {
|
||||
|
@ -75,7 +75,7 @@ const Handle: ParentComponent<Record<string, any>> = (props) => {
|
|||
const context = useContext(ContextMenu)!;
|
||||
const [handle, setHandle] = createSignal<HTMLElement>();
|
||||
|
||||
return <span {...rest} ref={setHandle} style={`anchor-name: --context-menu-handle-${createUniqueId()};`} oncontextmenu={(e) => {
|
||||
return <span {...rest} ref={setHandle} style={`anchor-name: --context-menu-${createUniqueId()};`} oncontextmenu={(e) => {
|
||||
e.preventDefault();
|
||||
|
||||
context.show(handle()!);
|
||||
|
@ -84,4 +84,7 @@ const Handle: ParentComponent<Record<string, any>> = (props) => {
|
|||
}}>{local.children}</span>;
|
||||
};
|
||||
|
||||
let handleCounter = 0;
|
||||
const createUniqueId = () => `handle-${handleCounter++}`
|
||||
|
||||
export const Context = { Root, Menu, Handle };
|
|
@ -1,4 +1,4 @@
|
|||
import { Accessor, children, Component, createContext, createEffect, createMemo, JSX, ParentComponent, ParentProps, Show, useContext } from 'solid-js';
|
||||
import { Accessor, children, Component, createContext, createEffect, createMemo, For, JSX, ParentComponent, ParentProps, Show, useContext } from 'solid-js';
|
||||
|
||||
interface CommandContextType {
|
||||
set(commands: CommandType<any>[]): void;
|
||||
|
@ -115,19 +115,27 @@ const Context = <T extends (...args: any[]) => any = any>(props: ParentProps<{ f
|
|||
};
|
||||
|
||||
const Handle: Component<{ command: CommandType }> = (props) => {
|
||||
return <>
|
||||
return <samp>
|
||||
{props.command.label}
|
||||
<Show when={props.command.shortcut}>{
|
||||
shortcut => {
|
||||
const shift = shortcut().modifier & Modifier.Shift ? 'Shft+' : '';
|
||||
const ctrl = shortcut().modifier & Modifier.Control ? 'Ctrl+' : '';
|
||||
const meta = shortcut().modifier & Modifier.Meta ? 'Meta+' : '';
|
||||
const alt = shortcut().modifier & Modifier.Alt ? 'Alt+' : '';
|
||||
const modifier = shortcut().modifier;
|
||||
const modifierMap: Record<number, string> = {
|
||||
[Modifier.Shift]: 'Shft',
|
||||
[Modifier.Control]: 'Ctrl',
|
||||
[Modifier.Meta]: 'Meta',
|
||||
[Modifier.Alt]: 'Alt',
|
||||
};
|
||||
|
||||
return <sub>{ctrl}{shift}{meta}{alt}{shortcut().key}</sub>;
|
||||
return <>
|
||||
<For each={Object.values(Modifier).filter((m): m is number => typeof m === 'number').filter(m => modifier & m)}>{
|
||||
(m) => <><kbd>{modifierMap[m]}</kbd>+</>
|
||||
}</For>
|
||||
<kbd>{shortcut().key}</kbd>
|
||||
</>;
|
||||
}
|
||||
}</Show>
|
||||
</>;
|
||||
</samp>;
|
||||
};
|
||||
|
||||
export const Command = { Root, Handle, Add, Context };
|
||||
|
|
|
@ -182,7 +182,7 @@ const Root: ParentComponent<{}> = (props) => {
|
|||
const Mount: Component = (props) => {
|
||||
const menu = useMenu();
|
||||
|
||||
return <div class={css.root} ref={menu.setRef} />;
|
||||
return <menu class={css.root} ref={menu.setRef} />;
|
||||
};
|
||||
|
||||
export const Menu = { Mount, Root, Item, Separator } as const;
|
||||
|
@ -233,7 +233,7 @@ export const CommandPalette: Component<{ api?: (api: CommandPaletteApi) => any,
|
|||
};
|
||||
|
||||
return <dialog ref={setRoot} class={css.commandPalette} onClose={() => setOpen(false)}>
|
||||
<SearchableList<CommandType> items={context.commands()} keySelector={item => item.label} context={setSearch} onSubmit={onSubmit}>{
|
||||
<SearchableList title="command palette" items={context.commands()} keySelector={item => item.label} context={setSearch} onSubmit={onSubmit}>{
|
||||
(item, ctx) => <For each={item.label.split(ctx.filter())}>{
|
||||
(part, index) => <>
|
||||
<Show when={index() !== 0}><b>{ctx.filter()}</b></Show>
|
||||
|
@ -258,6 +258,7 @@ interface SearchContext<T> {
|
|||
|
||||
interface SearchableListProps<T> {
|
||||
items: T[];
|
||||
title?: string;
|
||||
keySelector(item: T): string;
|
||||
filter?: (item: T, search: string) => boolean;
|
||||
children(item: T, context: SearchContext<T>): JSX.Element;
|
||||
|
@ -333,15 +334,17 @@ function SearchableList<T>(props: SearchableListProps<T>): JSX.Element {
|
|||
props.onSubmit?.(v);
|
||||
};
|
||||
|
||||
return <form method="dialog" class={css.search} onkeydown={onKeyDown} onsubmit={onSubmit}>
|
||||
<input id={`search-${id}`} ref={setInput} value={term()} oninput={(e) => setTerm(e.target.value)} placeholder="start typing for command" autofocus autocomplete="off" enterkeyhint="go" />
|
||||
return <search title={props.title}>
|
||||
<form method="dialog" class={css.search} onkeydown={onKeyDown} onsubmit={onSubmit}>
|
||||
<input id={`search-${id}`} ref={setInput} value={term()} oninput={(e) => setTerm(e.target.value)} placeholder="start typing for command" autofocus autocomplete="off" enterkeyhint="go" />
|
||||
|
||||
<output for={`search-${id}`}>
|
||||
<For each={results()}>{
|
||||
(result, index) => <div classList={{ [css.selected]: index() === selected() }}>{props.children(result, ctx)}</div>
|
||||
}</For>
|
||||
</output>
|
||||
</form>;
|
||||
<output for={`search-${id}`}>
|
||||
<For each={results()}>{
|
||||
(result, index) => <div classList={{ [css.selected]: index() === selected() }}>{props.children(result, ctx)}</div>
|
||||
}</For>
|
||||
</output>
|
||||
</form>
|
||||
</search>;
|
||||
};
|
||||
|
||||
declare module "solid-js" {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Accessor, children, createContext, createEffect, createMemo, createRenderEffect, createSignal, createUniqueId, onCleanup, onMount, ParentComponent, ParentProps, Setter, Signal, useContext } from "solid-js";
|
||||
import { Accessor, children, createContext, createEffect, createMemo, createRenderEffect, createSignal, onCleanup, onMount, ParentComponent, ParentProps, Setter, Signal, useContext } from "solid-js";
|
||||
import { createStore } from "solid-js/store";
|
||||
import { isServer } from "solid-js/web";
|
||||
import css from "./index.module.css";
|
||||
|
@ -280,6 +280,9 @@ export function selectable<T extends object>(element: HTMLElement, options: Acce
|
|||
element.dataset.selectionKey = selectionKey;
|
||||
};
|
||||
|
||||
let keyCounter = 0;
|
||||
const createUniqueId = () => `key-${keyCounter++}`;
|
||||
|
||||
declare module "solid-js" {
|
||||
namespace JSX {
|
||||
interface Directives {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue