Fix overflow issues in React tags box

- Properly truncate and ellipsize long tags
- Show scrollbar if tags go off the bottom of the pane

These both improve on the pre-React version, which didn't properly
truncate tags (at least in the current version, though I think it used
to) and scrolled the Add button off the top of the screen.
This commit is contained in:
Dan Stillman 2019-11-13 05:28:03 -05:00
parent 3e3e0b016d
commit 5ba5e70b9d
7 changed files with 53 additions and 13 deletions

View file

@ -410,13 +410,15 @@ const TagsBox = React.forwardRef((props, ref) => {
<div className="tags-box-count">{renderCount()}</div> <div className="tags-box-count">{renderCount()}</div>
<div><button onClick={handleAddTag}>Add</button></div> <div><button onClick={handleAddTag}>Add</button></div>
</div> </div>
<ul className="tags-box-list"> <div className="tags-box-list-container">
{displayTags.map(tag => renderTagRow(tag))} <ul className="tags-box-list">
</ul> {displayTags.map(tag => renderTagRow(tag))}
<span </ul>
tabIndex="0" <span
onFocus={handleAddTag} tabIndex="0"
/> onFocus={handleAddTag}
/>
</div>
</div> </div>
); );
}); });

View file

@ -190,7 +190,8 @@ var ZoteroItemPane = new function() {
ref={_tagsBox} ref={_tagsBox}
onResetSelection={focusItemsList} onResetSelection={focusItemsList}
/>, />,
document.getElementById('tags-box-container') document.getElementById('tags-box-container'),
() => ZoteroPane.updateTagsBoxSize()
); );
} }

View file

@ -105,6 +105,7 @@ var ZoteroPane = new function()
window.addEventListener("resize", () => { window.addEventListener("resize", () => {
this.updateWindow(); this.updateWindow();
this.updateToolbarPosition(); this.updateToolbarPosition();
this.updateTagsBoxSize();
}); });
window.setTimeout(this.updateToolbarPosition.bind(this), 0); window.setTimeout(this.updateToolbarPosition.bind(this), 0);
@ -4904,6 +4905,7 @@ var ZoteroPane = new function()
} }
this.updateToolbarPosition(); this.updateToolbarPosition();
this.updateTagsBoxSize();
} }
@ -5024,6 +5026,25 @@ var ZoteroPane = new function()
this.handleTagSelectorResize(); this.handleTagSelectorResize();
} }
/**
* Set an explicit height on the tags list to show a scroll bar if necessary
*
* This really should be be possible via CSS alone, but I couldn't get it to work, either
* because I was doing something wrong or because the XUL layout engine was messing with me.
* Revisit when we're all HTML.
*/
this.updateTagsBoxSize = function () {
var pane = document.querySelector('#zotero-item-pane');
var header = document.querySelector('#zotero-item-pane .tags-box-header');
var list = document.querySelector('#zotero-item-pane .tags-box-list');
if (pane && header && list) {
let height = pane.getBoundingClientRect().height
- header.getBoundingClientRect().height
- 35; // a little padding
list.style.height = height + 'px';
}
};
/** /**
* Opens the about dialog * Opens the about dialog
*/ */

View file

@ -551,8 +551,8 @@
</vbox> </vbox>
<splitter id="zotero-items-splitter" resizebefore="closest" resizeafter="closest" collapse="after" orient="horizontal" zotero-persist="state orient" <splitter id="zotero-items-splitter" resizebefore="closest" resizeafter="closest" collapse="after" orient="horizontal" zotero-persist="state orient"
onmousemove="ZoteroPane_Local.updateToolbarPosition()" onmousemove="ZoteroPane.updateToolbarPosition(); ZoteroPane.updateTagsBoxSize()"
oncommand="ZoteroPane_Local.updateToolbarPosition()"> oncommand="ZoteroPane.updateToolbarPosition(); ZoteroPane.updateTagsBoxSize()">
<grippy id="zotero-items-grippy"/> <grippy id="zotero-items-grippy"/>
</splitter> </splitter>

View file

@ -288,6 +288,7 @@
{ {
width: 338px; width: 338px;
min-width: 338px; min-width: 338px;
overflow-y: hidden;
} }
#zotero-layout-switcher #zotero-layout-switcher

View file

@ -7,4 +7,11 @@ input.editable-control {
textarea.editable-control { textarea.editable-control {
font-family: inherit; font-family: inherit;
font-size: inherit; font-size: inherit;
}
.editable-content {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
} }

View file

@ -8,7 +8,13 @@
} }
.tags-box { .tags-box {
$item-pane-width: 330px;
$icon-width: 16px;
$delete-button-width: 20px;
$li-side-margin: 6px;
flex-grow: 1; flex-grow: 1;
width: 330px;
.tags-box-header { .tags-box-header {
display: flex; display: flex;
@ -32,12 +38,13 @@
ul.tags-box-list { ul.tags-box-list {
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 0; padding: 2px 0 0; // Leave space for textbox border on top tag
overflow-y: auto;
} }
ul.tags-box-list > li { ul.tags-box-list > li {
display: flex; display: flex;
margin: 3px 6px 3px 6px; margin: 3px $li-side-margin;
align-items: center; align-items: center;
height: 1.5em; height: 1.5em;
@ -45,7 +52,7 @@
border: 0; border: 0;
background: none; background: none;
padding: 0; padding: 0;
width: 20px; width: $delete-button-width;
height: 18px; height: 18px;
} }
} }
@ -53,6 +60,7 @@
.editable-container { .editable-container {
flex-grow: 1; flex-grow: 1;
margin: 0 2px; margin: 0 2px;
width: $item-pane-width - $icon-width - $delete-button-width - ($li-side-margin * 2);
} }
ul.tags-box-list > li:not(.multiline) .editable-container { ul.tags-box-list > li:not(.multiline) .editable-container {