diff --git a/index.html b/index.html index 906607b..9f0e278 100644 --- a/index.html +++ b/index.html @@ -17,9 +17,11 @@ class FileGroup extends HTMLElement { super() this.attachShadow({mode: 'open'}) this.headerEl = document.createElement('div') - this.filesEl = document.createElement('div') + this.headerEl.classList.add('header') + this.contentEl = document.createElement('div') + this.contentEl.classList.add('content') this.shadowRoot.appendChild(this.headerEl) - this.shadowRoot.appendChild(this.filesEl) + this.shadowRoot.appendChild(this.contentEl) } connectedCallback() { @@ -43,11 +45,13 @@ class FileGroup extends HTMLElement { ` this.shadowRoot.appendChild(style) this.addNewFile() + this.addNewFile() + this.addNewFile() } addNewFile() { const el = document.createElement('m-file-view') - this.filesEl.appendChild(el) + this.contentEl.appendChild(el) } } @@ -58,6 +62,7 @@ class FileView extends HTMLElement { this.headerEl = document.createElement('div') this.headerEl.classList.add('header') this.contentEl = document.createElement('div') + this.contentEl.classList.add('content') this.shadowRoot.appendChild(this.headerEl) this.shadowRoot.appendChild(this.contentEl) } @@ -73,21 +78,75 @@ class FileView extends HTMLElement { div.header { display: flex; flex-direction: row; - background: yellow; } .name { flex-grow: 1; } + div.content { + display: flex; + flex-direction: column; + align-items: stretch; + } ` this.shadowRoot.appendChild(style) this.nameEl = document.createElement('input') this.nameEl.classList.add('name') this.headerEl.appendChild(this.nameEl) + this.editEl = document.createElement('m-text-edit') + this.contentEl.appendChild(this.editEl) + } +} + +class TextEdit extends HTMLElement { + constructor() { + super() + this.attachShadow({mode: 'open'}) + } + + connectedCallback() { + // https://css-tricks.com/the-cleanest-trick-for-autogrowing-textareas/ + const style = document.createElement('style') + style.textContent = ` + :host { + display: flex; + flex-direction: column; + align-items: stretch; + margin: 5px 0; + } + div.stack { + display: grid; + } + div.stack::after { + content: attr(data-copy) " "; + visibility: hidden; + resize: none; + overflow: hidden; + } + div.stack::after, div.stack > textarea { + white-space: pre-wrap; + border: 1px solid #444; + padding: 5px; + font: inherit; + font-family: monospace; + grid-area: 1 / 1 / 2 / 2; + } + ` + this.shadowRoot.appendChild(style) + const stackEl = document.createElement('div') + stackEl.classList.add('stack') + this.textEl = document.createElement('textarea') + this.textEl.classList.add('text') + stackEl.appendChild(this.textEl) + this.shadowRoot.appendChild(stackEl) + this.textEl.addEventListener('input', () => { + stackEl.dataset.copy = this.textEl.value + }) } } customElements.define('m-file-group', FileGroup) customElements.define('m-file-view', FileView) +customElements.define('m-text-edit', TextEdit) const fileGroup = document.createElement('m-file-group') document.body.appendChild(fileGroup)