From c7b02f02ad0a7e2888f2d7d3599719e59bbd1ee2 Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Thu, 13 Nov 2025 14:56:02 +0100 Subject: frontend: design prototype --- static/widgets/editable/index.css | 36 ++++++++++++++++++++++ static/widgets/editable/index.js | 65 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 static/widgets/editable/index.css create mode 100644 static/widgets/editable/index.js (limited to 'static/widgets/editable') diff --git a/static/widgets/editable/index.css b/static/widgets/editable/index.css new file mode 100644 index 0000000..b474370 --- /dev/null +++ b/static/widgets/editable/index.css @@ -0,0 +1,36 @@ + +#container { + width: 100%; + background: var(--card-background); + box-shadow: var(--shadow); + border-radius: var(--border-radius); + display: grid; + grid-template-columns: min-content auto min-content; +} + +#container label { + user-select: none; + font-weight: bold; + background: var(--primary); + color: var(--fg-primary); + align-content: center; + padding: 10px; + border-top-left-radius: var(--border-radius); + border-bottom-left-radius: var(--border-radius); +} + +#container input { + background: var(--card-background); + user-select: none; + font-size: 1em; +} + +#container input:read-only { + caret-color: transparent; +} + +#edit { + width: 35px; + padding: 10px; + cursor: pointer; +} diff --git a/static/widgets/editable/index.js b/static/widgets/editable/index.js new file mode 100644 index 0000000..8a72aff --- /dev/null +++ b/static/widgets/editable/index.js @@ -0,0 +1,65 @@ +import * as sfw from 'sfw'; +const { Div, Label, Input } = sfw.element.native; + +import icons from '../../icons/index.js'; + +const css = await sfw.css(import.meta.url, './index.css'); + +export default class Editable extends sfw.element.Container { + #label + #input + #edit + + constructor() { + super({ css }); + + this.body.append( + Div.new({ + id: 'container', + children: [ + this.#label = Label.new({ htmlFor: 'input' }), + this.#input = Input.new({ + readOnly: true, + onkeydown: (e) => { + if (e.key === 'Enter') { + this.#input.readOnly = true; + this.#update() + } + }, + }), + this.#edit = Div.new({ + id: 'edit', + children: [ icons.edit ], + onclick: () => { + this.#input.readOnly = !this.#input.readOnly; + this.#update(); + } + }), + ], + }) + ); + } + + #update() { + this.#edit.innerHTML = ''; + this.#edit.append( + this.#input.readOnly ? icons.edit : icons.check + ); + + if (!this.#input.readOnly) { + this.#input.select(); + } + } + + set title(value) { + this.#label.innerText = value; + } + + set value(value) { + this.#input.value = value; + } + + set type(type) { + this.#input.type = type; + } +} -- cgit v1.2.3-70-g09d2