started introduction of splitting into tabs
This commit is contained in:
parent
1472bd8116
commit
b03f80f34f
10 changed files with 255 additions and 159 deletions
|
@ -1,4 +1,4 @@
|
|||
import { Accessor, Component, createContext, createEffect, createMemo, createSignal, createUniqueId, For, JSX, ParentComponent, useContext } from "solid-js";
|
||||
import { Accessor, Component, createContext, createEffect, createMemo, createSignal, createUniqueId, For, JSX, ParentComponent, splitProps, useContext } from "solid-js";
|
||||
import { CommandType } from "./index";
|
||||
import css from "./contextMenu.module.css";
|
||||
|
||||
|
@ -69,16 +69,19 @@ const Menu: Component<{ children: (command: CommandType) => JSX.Element }> = (pr
|
|||
</ul>;
|
||||
};
|
||||
|
||||
const Handle: ParentComponent = (props) => {
|
||||
const context = useContext(ContextMenu)!;
|
||||
const Handle: ParentComponent<Record<string, any>> = (props) => {
|
||||
const [local, rest] = splitProps(props, ['children']);
|
||||
|
||||
return <span style={`anchor-name: --context-menu-handle-${createUniqueId()};`} oncontextmenu={(e) => {
|
||||
const context = useContext(ContextMenu)!;
|
||||
const [handle, setHandle] = createSignal<HTMLElement>();
|
||||
|
||||
return <span {...rest} ref={setHandle} style={`anchor-name: --context-menu-handle-${createUniqueId()};`} oncontextmenu={(e) => {
|
||||
e.preventDefault();
|
||||
|
||||
context.show(e.target as HTMLElement);
|
||||
context.show(handle()!);
|
||||
|
||||
return false;
|
||||
}}>{props.children}</span>;
|
||||
}}>{local.children}</span>;
|
||||
};
|
||||
|
||||
export const Context = { Root, Menu, Handle };
|
|
@ -42,7 +42,6 @@ export const noop = Object.defineProperties(createCommand('noop', () => { }), {
|
|||
},
|
||||
}) as CommandType & { withLabel(label: string): CommandType };
|
||||
|
||||
|
||||
export const Command: Component<{ command: CommandType }> = (props) => {
|
||||
return <>
|
||||
{props.command.label}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Accessor, Component, createContext, createEffect, createMemo, createSignal, For, onMount, ParentComponent, Show, useContext } from "solid-js";
|
||||
import { Accessor, Component, createContext, createEffect, createMemo, createRenderEffect, createSignal, For, onMount, ParentComponent, Show, useContext } from "solid-js";
|
||||
import { createStore, unwrap } from "solid-js/store";
|
||||
import { SelectionProvider, useSelection, selectable } from "../selectable";
|
||||
import { debounce, deepCopy, deepDiff, Mutation } from "~/utilities";
|
||||
|
@ -160,7 +160,7 @@ const Row: Component<{ entry: Entry, path?: string[] }> = (props) => {
|
|||
return <Show when={isLeaf(value)} fallback={<Group key={key} entry={value as Entry} path={path} />}>
|
||||
<div class={css.row} use:selectable={{ value, key: k }}>
|
||||
<div class={css.cell}>
|
||||
<input type="checkbox" checked={isSelected()} oninput={() => context.select([k])} />
|
||||
<input type="checkbox" checked={isSelected()} on:input={() => context.select([k])} />
|
||||
</div>
|
||||
|
||||
<div class={css.cell}>
|
||||
|
@ -187,16 +187,22 @@ const Group: Component<{ key: string, entry: Entry, path: string[] }> = (props)
|
|||
};
|
||||
|
||||
const TextArea: Component<{ key: string, value: string, lang: string, oninput?: (event: InputEvent) => any }> = (props) => {
|
||||
let element: HTMLTextAreaElement;
|
||||
const [element, setElement] = createSignal<HTMLTextAreaElement>();
|
||||
|
||||
const resize = () => {
|
||||
element.style.height = `1px`;
|
||||
element.style.height = `${2 + element.scrollHeight}px`;
|
||||
const el = element();
|
||||
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
|
||||
el.style.height = `1px`;
|
||||
el.style.height = `${2 + element()!.scrollHeight}px`;
|
||||
};
|
||||
|
||||
const mutate = debounce(() => {
|
||||
props.oninput?.(new InputEvent('input', {
|
||||
data: element.value.trim(),
|
||||
data: element()?.value.trim(),
|
||||
}))
|
||||
}, 300);
|
||||
|
||||
|
@ -205,12 +211,14 @@ const TextArea: Component<{ key: string, value: string, lang: string, oninput?:
|
|||
mutate();
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
createEffect(() => {
|
||||
props.value;
|
||||
|
||||
resize();
|
||||
});
|
||||
|
||||
return <textarea
|
||||
ref={element}
|
||||
ref={setElement}
|
||||
value={props.value}
|
||||
lang={props.lang}
|
||||
placeholder={props.lang}
|
||||
|
@ -218,6 +226,5 @@ const TextArea: Component<{ key: string, value: string, lang: string, oninput?:
|
|||
spellcheck
|
||||
wrap="soft"
|
||||
onkeyup={onKeyUp}
|
||||
on:pointerdown={(e: PointerEvent) => e.stopPropagation()}
|
||||
/>
|
||||
};
|
|
@ -1,13 +1,11 @@
|
|||
import Dexie, { EntityTable } from "dexie";
|
||||
import { createContext, useContext } from "solid-js";
|
||||
import { createContext, ParentComponent, useContext } from "solid-js";
|
||||
import { isServer } from "solid-js/web";
|
||||
import * as json from './parser/json';
|
||||
|
||||
type Handle = FileSystemFileHandle | FileSystemDirectoryHandle;
|
||||
|
||||
interface FileEntity {
|
||||
name: string;
|
||||
handle: Handle;
|
||||
handle: FileSystemDirectoryHandle;
|
||||
}
|
||||
|
||||
type Store = Dexie & {
|
||||
|
@ -15,9 +13,9 @@ type Store = Dexie & {
|
|||
};
|
||||
|
||||
interface FilesContextType {
|
||||
set(name: string, handle: Handle): Promise<void>;
|
||||
get(name: string): Promise<Handle | undefined>;
|
||||
list(): Promise<Handle[]>;
|
||||
set(name: string, handle: FileSystemDirectoryHandle): Promise<void>;
|
||||
get(name: string): Promise<FileSystemDirectoryHandle | undefined>;
|
||||
list(): Promise<FileSystemDirectoryHandle[]>;
|
||||
}
|
||||
|
||||
const FilesContext = createContext<FilesContextType>();
|
||||
|
@ -30,7 +28,7 @@ const clientContext = (): FilesContextType => {
|
|||
});
|
||||
|
||||
return {
|
||||
async set(name: string, handle: Handle) {
|
||||
async set(name: string, handle: FileSystemDirectoryHandle) {
|
||||
await db.files.put({ name, handle });
|
||||
},
|
||||
async get(name: string) {
|
||||
|
@ -52,11 +50,11 @@ const serverContext = (): FilesContextType => ({
|
|||
return Promise.resolve(undefined);
|
||||
},
|
||||
list() {
|
||||
return Promise.resolve<Handle[]>([]);
|
||||
return Promise.resolve<FileSystemDirectoryHandle[]>([]);
|
||||
},
|
||||
});
|
||||
|
||||
export const FilesProvider = (props) => {
|
||||
export const FilesProvider: ParentComponent = (props) => {
|
||||
const ctx = isServer ? serverContext() : clientContext();
|
||||
|
||||
return <FilesContext.Provider value={ctx}>{props.children}</FilesContext.Provider>;
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Accessor, children, createContext, createEffect, createMemo, createRend
|
|||
import { createStore } from "solid-js/store";
|
||||
import { isServer } from "solid-js/web";
|
||||
import css from "./index.module.css";
|
||||
import { isFocusable } from "~/utilities";
|
||||
|
||||
enum Modifier {
|
||||
None = 0,
|
||||
|
@ -68,6 +69,8 @@ export const SelectionProvider: ParentComponent<{ selection?: SelectionHandler,
|
|||
mode = SelectionMode.Toggle;
|
||||
}
|
||||
|
||||
console.log(selection, mode);
|
||||
|
||||
setState('selection', existing => {
|
||||
switch (mode) {
|
||||
case SelectionMode.Toggle: {
|
||||
|
@ -230,7 +233,9 @@ export const selectable = (element: HTMLElement, options: Accessor<{ value: obje
|
|||
element.dataset.selected = isSelected() ? 'true' : undefined;
|
||||
});
|
||||
|
||||
const onPointerDown = (e: PointerEvent) => {
|
||||
const onPointerDown = (e: Event) => {
|
||||
// TODO :: find out if the cell clicked is editable and early exit after that
|
||||
|
||||
const [latest, setLatest] = internal.latest
|
||||
const [modifier] = internal.modifier
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue