diff web/EditChoice.ts @ 2376:4556eebe5d73

topdir reorgs; let pdm have its src/ dir; separate vite area from light9/
author drewp@bigasterisk.com
date Sun, 12 May 2024 19:02:10 -0700
parents light9/web/EditChoice.ts@2aeceb6f03aa
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/EditChoice.ts	Sun May 12 19:02:10 2024 -0700
@@ -0,0 +1,118 @@
+// see light9/editchoice.py for gtk version
+import debug from "debug";
+import { css, html, LitElement } from "lit";
+import { customElement, property } from "lit/decorators.js";
+import { NamedNode } from "n3";
+import { $V, Vector } from "sylvester";
+export { ResourceDisplay } from "../web/ResourceDisplay";
+const log = debug("editchoice");
+const RDFS = "http://www.w3.org/2000/01/rdf-schema#";
+
+function setupDrop(
+  senseElem: HTMLElement,
+  highlightElem: HTMLElement,
+  coordinateOriginElem: HTMLElement | null,
+  onDrop: (uri: NamedNode, pos: Vector | null) => void
+) {
+  const highlight = () => highlightElem.classList.add("dragging");
+  const unhighlight = () => highlightElem.classList.remove("dragging");
+
+  senseElem.addEventListener("drag", (event: DragEvent) => { });
+
+  senseElem.addEventListener("dragstart", (event: DragEvent) => { });
+
+  senseElem.addEventListener("dragend", (event: DragEvent) => { });
+
+  senseElem.addEventListener("dragover", (event: DragEvent) => {
+    event.preventDefault();
+    event.dataTransfer!.dropEffect = "copy";
+    highlight();
+  });
+
+  senseElem.addEventListener("dragenter", (event: DragEvent) => {
+    highlight();
+  });
+
+  senseElem.addEventListener("dragleave", (event: DragEvent) => {
+    unhighlight();
+  });
+
+  senseElem.addEventListener("drop", (event: DragEvent) => {
+    event.preventDefault();
+    const uri = new NamedNode(event.dataTransfer!.getData("text/uri-list"));
+
+    let pos: Vector | null = null;
+    if (coordinateOriginElem != null) {
+      const root = coordinateOriginElem.getBoundingClientRect();
+      pos = $V([event.pageX - root.left, event.pageY - root.top]);
+    }
+
+    try {
+      onDrop(uri, pos);
+    } catch (e) {
+      log(e);
+    }
+    unhighlight();
+  });
+}
+
+// Picks a URI based on the caller setting the property OR
+// the user drag-and-dropping a text/uri-list resource (probably
+// an <resource-display> or <a href> tag)
+@customElement("edit-choice")
+export class EditChoice extends LitElement {
+  @property() uri?: NamedNode
+  @property({ type: Boolean }) nounlink = false;
+  @property({ type: Boolean }) rename = false;
+  static styles = [
+    css`
+      :host {
+        display: inline-block;
+        background: #141448;
+        /* min-width: 10em; */
+        padding: 3px 8px;
+      }
+      .dragging {
+        background: rgba(126, 52, 245, 0.0784313725490196);
+        box-shadow: 0 0 20px #ffff00;
+      }
+      a {
+        color: #8e8eff;
+        padding: 3px;
+        display: inline-block;
+        font-size: 145%;
+      }
+    `,
+  ];
+  render() {
+    const unlink = html`
+    <button @click=${this.unlink}>Unlink</button>
+    `
+    return html`
+      <resource-display .uri=${this.uri} ?rename=${this.rename}></resource-display>
+      ${this.nounlink ? html`` : unlink}
+    `;
+  }
+
+  constructor() {
+    super();
+    setupDrop(this, this, null, this._setUri.bind(this));
+  }
+
+  // updated(changedProperties: PropertyValues) {
+  //   log('cp' ,changedProperties)
+  //   if (changedProperties.has("box")) {
+  //     log('setupdrop', this.box)
+  //     setupDrop(this.box, this.box, null, this._setUri.bind(this));
+  //   }
+  // }
+
+  _setUri(u?: NamedNode) {
+    this.uri = u;
+    this.dispatchEvent(new CustomEvent("edited", { detail: { newValue: u } }));
+  }
+
+  unlink() {
+    return this._setUri(undefined);
+  }
+}