diff web/live/Light9Listbox.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/live/Light9Listbox.ts@06bf6dae8e64
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/live/Light9Listbox.ts	Sun May 12 19:02:10 2024 -0700
@@ -0,0 +1,76 @@
+import debug from "debug";
+import { css, html, LitElement, PropertyValues } from "lit";
+import { customElement, property } from "lit/decorators.js";
+const log = debug("listbox");
+export type Choice = { uri: string; label: string };
+
+@customElement("light9-listbox")
+export class Light9Listbox extends LitElement {
+  static styles = [
+    css`
+      paper-listbox {
+        --paper-listbox-background-color: none;
+        --paper-listbox-color: white;
+        --paper-listbox: {
+          /* measure biggest item? use flex for columns? */
+          column-width: 9em;
+        }
+      }
+      paper-item {
+        --paper-item-min-height: 0;
+        --paper-item: {
+          display: block;
+          border: 1px outset #0f440f;
+          margin: 0 1px 5px 0;
+          background: #0b1d0b;
+        }
+      }
+      paper-item.iron-selected {
+        background: #7b7b4a;
+      }
+    `,
+  ];
+
+  render() {
+    return html`
+      <paper-listbox id="list" selected="{{value}}" attr-for-selected="uri" on-focus-changed="selectOnFocus">
+        <paper-item on-focus="selectOnFocus">None</paper-item>
+        <template is="dom-repeat" items="{{choices}}">
+          <paper-item on-focus="selectOnFocus" uri="{{item.uri}}">{{item.label}}</paper-item>
+        </template>
+      </paper-listbox>
+    `;
+  }
+  @property() choices: Array<Choice> = [];
+  @property() value: String | null = null;
+
+  constructor() {
+    super();
+  }
+  selectOnFocus(ev) {
+    if (ev.target.uri === undefined) {
+      // *don't* clear for this, or we can't cycle through all choices (including none) with up/down keys
+      //this.clear();
+      //return;
+    }
+    this.value = ev.target.uri;
+  }
+  updated(changedProperties: PropertyValues) {
+    if (changedProperties.has("value")) {
+      if (this.value === null) {
+        this.clear();
+      }
+    }
+  }
+  onValue(value: String | null) {
+    if (value === null) {
+      this.clear();
+    }
+  }
+  clear() {
+    this.querySelectorAll("paper-item").forEach(function (item) {
+      item.blur();
+    });
+    this.value = null;
+  }
+}