diff --git a/chrome/content/zotero/elements/editableText.js b/chrome/content/zotero/elements/editableText.js index e7c38d42c3..cbeba26753 100644 --- a/chrome/content/zotero/elements/editableText.js +++ b/chrome/content/zotero/elements/editableText.js @@ -41,7 +41,9 @@ 'aria-labelledby', 'value', 'nowrap', - 'autocomplete' + 'autocomplete', + 'min-lines', + 'max-lines' ]; get noWrap() { @@ -52,6 +54,15 @@ this.toggleAttribute('nowrap', noWrap); } + get minLines() { + return this.getAttribute('min-lines') || 0; + } + + get maxLines() { + return this.getAttribute('max-lines') || 0; + } + + get multiline() { return this.hasAttribute('multiline'); } @@ -266,6 +277,20 @@ } this._input.readOnly = this.readOnly; this._input.placeholder = this.placeholder; + + if (this._input.tagName == "textarea") { + // Reset to initial state + this.style.removeProperty("--min-visible-lines"); + this.style.removeProperty("--max-visible-lines"); + // Set how tall the textarea can/must be + if (this.minLines > 0) { + this.style.setProperty("--min-visible-lines", this.minLines); + } + if (this.maxLines > 0) { + this.style.setProperty("--max-visible-lines", this.maxLines); + } + } + if (this.ariaLabel.length) { this._input.setAttribute('aria-label', this.ariaLabel); } diff --git a/chrome/content/zotero/elements/itemBox.js b/chrome/content/zotero/elements/itemBox.js index d0f5ce2861..9948b13d62 100644 --- a/chrome/content/zotero/elements/itemBox.js +++ b/chrome/content/zotero/elements/itemBox.js @@ -1629,6 +1629,11 @@ async showEditor(elem) { Zotero.debug(`Showing editor for ${elem.getAttribute('fieldname')}`); var fieldName = elem.getAttribute('fieldname'); + + // Multiline field will be at least 6 lines + if (Zotero.ItemFields.isMultiline(fieldName)) { + elem.setAttribute("min-lines", 6); + } var [field, creatorIndex, creatorField] = fieldName.split('-'); let value; if (field == 'creator') { @@ -1977,6 +1982,10 @@ var fieldName = textbox.getAttribute('fieldname'); + // Multiline fields go back to occupying as much space as needed + if (Zotero.ItemFields.isMultiline(fieldName)) { + textbox.setAttribute("min-lines", 1); + } var value = textbox.value.trim(); var [field, creatorIndex, creatorField] = fieldName.split('-'); diff --git a/scss/abstracts/_mixins.scss b/scss/abstracts/_mixins.scss index c20f35e547..fbdf935a08 100644 --- a/scss/abstracts/_mixins.scss +++ b/scss/abstracts/_mixins.scss @@ -161,10 +161,6 @@ // allow input to be shrunk by other elements when the itemBox is narrow min-width: 0; } - // keep multiline fields as tall as they have to be unless they're focused - &[multiline] textarea:not(:focus) { - min-height: 1em; - } } .meta-label { diff --git a/scss/elements/_editableText.scss b/scss/elements/_editableText.scss index 98758e16b4..6dbaba84a7 100644 --- a/scss/elements/_editableText.scss +++ b/scss/elements/_editableText.scss @@ -9,17 +9,9 @@ } editable-text { - --min-visible-lines: 0; - --max-visible-lines: 6; - - &[multiline] { - --min-visible-lines: 5; - --max-visible-lines: 20; - } - - &[nowrap] { - --min-visible-lines: 1; - } + // Default variables overriden by max-lines, min-lines attribute + --min-visible-lines: 1; + --max-visible-lines: 1; &[tight] { @include comfortable { @@ -56,16 +48,23 @@ editable-text { font: inherit; line-height: inherit; overflow: hidden; - scrollbar-gutter: stable; } &:not([nowrap])::after, &:not([nowrap]) .input { grid-area: 1 / 1 / 2 / 2; overflow-wrap: anywhere; white-space: pre-wrap; - max-height: calc(2ex * var(--max-visible-lines)); - // Somehow this hides scroll arrows on windows when the content is short or empty - scrollbar-width: thin; + scrollbar-width: none; + } + + &[max-lines] { + &::after, .input { + max-height: calc(2ex * var(--max-visible-lines)); + scrollbar-width: auto; + } + &::after { + scrollbar-gutter: stable; + } } .input { @@ -104,12 +103,6 @@ editable-text { color: var(--fill-tertiary); } } - - &[multiline] { - .input { - min-height: 5em; - } - } &[nowrap] { .input:not(:focus, :hover) { text-overflow: ellipsis;