diff options
| author | Nathan Reiner <nathan@nathanreiner.xyz> | 2025-11-13 14:56:02 +0100 |
|---|---|---|
| committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2025-11-13 14:56:02 +0100 |
| commit | c7b02f02ad0a7e2888f2d7d3599719e59bbd1ee2 (patch) | |
| tree | 9f782daf2e2ff78559958f15e0b9ffe5ece78334 /static/widgets/editable/index.js | |
| parent | 7ee9d320e6ba9a84542d838892c43cf98b268552 (diff) | |
frontend: design prototype
Diffstat (limited to 'static/widgets/editable/index.js')
| -rw-r--r-- | static/widgets/editable/index.js | 65 |
1 files changed, 65 insertions, 0 deletions
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; + } +} |