more refactoring, add folder open indicators
This commit is contained in:
parent
b9c499a87e
commit
920cc53ce3
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { basicSetup } from "codemirror";
|
||||||
|
import { EditorView } from "@codemirror/view";
|
||||||
|
import { oneDark } from "@codemirror/theme-one-dark";
|
||||||
|
|
||||||
|
const fixedHeightEditor = EditorView.theme({
|
||||||
|
"&": {
|
||||||
|
height: "100%",
|
||||||
|
minHeight: "0px",
|
||||||
|
resize: "horizontal",
|
||||||
|
overflow: "auto",
|
||||||
|
width: "600px",
|
||||||
|
minWidth: "8em",
|
||||||
|
flex: "none",
|
||||||
|
},
|
||||||
|
".cm-scroller": { overflow: "auto" },
|
||||||
|
});
|
||||||
|
|
||||||
|
export class Editor {
|
||||||
|
view: EditorView;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.view = new EditorView({
|
||||||
|
doc: "Start document",
|
||||||
|
extensions: [basicSetup, oneDark, fixedHeightEditor],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get dom() {
|
||||||
|
return this.view.dom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,7 @@ async function openFolder() {
|
||||||
folderTreeState.val = folderTree;
|
folderTreeState.val = folderTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FolderTreeView = () => {
|
export const FolderTreeView = () => {
|
||||||
if (!folderTreeState.val) {
|
if (!folderTreeState.val) {
|
||||||
return v.div(
|
return v.div(
|
||||||
{ class: "text-center m-4" },
|
{ class: "text-center m-4" },
|
||||||
|
|
@ -21,10 +21,11 @@ const FolderTreeView = () => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return v.div(
|
return v.div(
|
||||||
|
{ class: "mx-1" },
|
||||||
v.div(
|
v.div(
|
||||||
{ class: "flex w-full" },
|
{ class: "flex w-full" },
|
||||||
v.span(
|
v.span(
|
||||||
{ class: "font-bold mx-1 flex-1" },
|
{ class: "font-bold flex-1" },
|
||||||
folderTreeState.val?.name ?? "No folder",
|
folderTreeState.val?.name ?? "No folder",
|
||||||
),
|
),
|
||||||
u.InlineButton(openFolder, "Refresh current folder", "⟳"),
|
u.InlineButton(openFolder, "Refresh current folder", "⟳"),
|
||||||
|
|
@ -37,20 +38,21 @@ const FolderTreeView = () => {
|
||||||
// TODO: determine if lazy DOM creation is better or not.
|
// TODO: determine if lazy DOM creation is better or not.
|
||||||
// Alternatively, investigate lazy FS traversal in main.
|
// Alternatively, investigate lazy FS traversal in main.
|
||||||
const FsItemView = (tree: FolderTree): HTMLElement => {
|
const FsItemView = (tree: FolderTree): HTMLElement => {
|
||||||
if (tree.type === "file") return v.p(tree.name);
|
if (tree.type === "file") return v.p(v.span("📄"), tree.name);
|
||||||
const isOpen = van.state(false);
|
const isOpen = van.state(false);
|
||||||
const children = () =>
|
const children = () =>
|
||||||
isOpen.val
|
isOpen.val
|
||||||
? v.div({ class: "ml-4" }, tree.children?.map(FsItemView))
|
? v.ul({}, tree.children?.map(FsItemView))
|
||||||
: v.div({ ariaBusy: true });
|
: v.div({ ariaBusy: true });
|
||||||
const folder = v.details(
|
const folder = v.details(
|
||||||
{ ontoggle: () => (isOpen.val = folder.open) },
|
{ class: "inline", ontoggle: () => (isOpen.val = folder.open) },
|
||||||
v.summary(tree.name),
|
v.summary(tree.name),
|
||||||
children,
|
children,
|
||||||
);
|
);
|
||||||
|
|
||||||
return folder;
|
return v.div(
|
||||||
|
{ class: "flex" },
|
||||||
|
v.span(() => (isOpen.val ? "📂" : "📁")),
|
||||||
|
folder,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mount the folder tree view to the nav
|
|
||||||
van.add(document.querySelector("aside nav"), FolderTreeView);
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1,8 @@
|
||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
details > summary {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
details > summary::-webkit-details-marker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,3 @@
|
||||||
/**
|
|
||||||
* This file will automatically be loaded by vite and run in the "renderer" context.
|
|
||||||
* To learn more about the differences between the "main" and the "renderer" context in
|
|
||||||
* Electron, visit:
|
|
||||||
*
|
|
||||||
* https://electronjs.org/docs/tutorial/process-model
|
|
||||||
*
|
|
||||||
* By default, Node.js integration in this file is disabled. When enabling Node.js integration
|
|
||||||
* in a renderer process, please be aware of potential security implications. You can read
|
|
||||||
* more about security risks here:
|
|
||||||
*
|
|
||||||
* https://electronjs.org/docs/tutorial/security
|
|
||||||
*
|
|
||||||
* To enable Node.js integration in this file, open up `main.ts` and enable the `nodeIntegration`
|
|
||||||
* flag:
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* // Create the browser window.
|
|
||||||
* mainWindow = new BrowserWindow({
|
|
||||||
* width: 800,
|
|
||||||
* height: 600,
|
|
||||||
* webPreferences: {
|
|
||||||
* nodeIntegration: true
|
|
||||||
* }
|
|
||||||
* });
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
|
|
||||||
// import "./pico.jade.css";
|
// import "./pico.jade.css";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
|
||||||
|
|
@ -33,50 +5,32 @@ import van from "vanjs-core";
|
||||||
import * as vanX from "vanjs-ext";
|
import * as vanX from "vanjs-ext";
|
||||||
const v = van.tags;
|
const v = van.tags;
|
||||||
|
|
||||||
import { basicSetup } from "codemirror";
|
import { Editor } from "./editor";
|
||||||
import { EditorView } from "@codemirror/view";
|
import { FolderTreeView } from "./foldernav";
|
||||||
import { oneDark } from "@codemirror/theme-one-dark";
|
import * as u from "./utils";
|
||||||
|
|
||||||
import "./foldernav.ts";
|
const EditorWrapper = (editor: any, del: any, k: any) =>
|
||||||
|
v.div(
|
||||||
const fixedHeightEditor = EditorView.theme({
|
{ class: "flex flex-col" },
|
||||||
"&": {
|
v.div(
|
||||||
height: "100%",
|
{ class: "flex" },
|
||||||
minHeight: "0px",
|
v.span({ class: "mx-1 flex-1" }, "Editor " + k),
|
||||||
resize: "horizontal",
|
u.InlineButton(del, "Close", "❌"),
|
||||||
overflow: "auto",
|
),
|
||||||
width: "600px",
|
v.div({ class: "h-full" }, editor.val.dom),
|
||||||
minWidth: "8em",
|
);
|
||||||
flex: "none",
|
|
||||||
},
|
|
||||||
".cm-scroller": { overflow: "auto" },
|
|
||||||
});
|
|
||||||
|
|
||||||
class EditorColumn {
|
|
||||||
view: EditorView;
|
|
||||||
wrapper: HTMLElement;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.view = new EditorView({
|
|
||||||
doc: "Start document",
|
|
||||||
extensions: [basicSetup, oneDark, fixedHeightEditor],
|
|
||||||
});
|
|
||||||
console.log("Character width: ", this.view.defaultCharacterWidth);
|
|
||||||
this.wrapper = v.div({ class: "editorWrapper min-h-0" }, this.view.dom);
|
|
||||||
}
|
|
||||||
get dom() {
|
|
||||||
return this.wrapper;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create and mount editor list
|
// Create and mount editor list
|
||||||
const editors = vanX.reactive([]);
|
const editors = vanX.reactive([]);
|
||||||
vanX.list(document.getElementById("editorGrid"), editors, (v) => v.val.dom);
|
vanX.list(document.getElementById("editorGrid"), editors, EditorWrapper);
|
||||||
|
|
||||||
function addView() {
|
function addView() {
|
||||||
editors.push(vanX.noreactive(new EditorColumn()));
|
editors.push(vanX.noreactive(new Editor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("addEditor")?.addEventListener("click", addView);
|
document.getElementById("addEditor")?.addEventListener("click", addView);
|
||||||
|
|
||||||
addView();
|
addView();
|
||||||
|
|
||||||
|
// Mount the folder tree view to the nav
|
||||||
|
van.add(document.querySelector("aside nav"), FolderTreeView);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue