Fix item pane header (#4159)
* Improve feed item pane header (fixes #4141) * Show item pane custom head when headerMode is none (fixes #4116) * fx115: Fix button style on windows (fixes #4120) * Move split-menu-button styles to SCSS
This commit is contained in:
parent
845f11b1da
commit
a6076ce76c
12 changed files with 214 additions and 103 deletions
|
@ -338,6 +338,7 @@
|
|||
|
||||
let toggleReadButton = doc.createXULElement("button");
|
||||
toggleReadButton.classList.add("feed-item-toggleRead-button");
|
||||
toggleReadButton.classList.add("no-shrink-button");
|
||||
toggleReadButton.addEventListener("command", () => {
|
||||
ZoteroPane.toggleSelectedItemsRead();
|
||||
});
|
||||
|
@ -447,6 +448,12 @@
|
|||
+ key + ')';
|
||||
elem.title = tooltip;
|
||||
elem.image = this._translationTarget.treeViewImage;
|
||||
|
||||
// Set button width to take up the free width when the text is too long
|
||||
// to prevent another button from growing
|
||||
// 6px button padding + 16px icon + 4 px gap + ${textWidth} + 6px gap
|
||||
// + 1px separator + 6px gap + 8px dropdown arrow + 6px button padding
|
||||
elem.style.flexBasis = `${elem.querySelector(`[anonid="button-text"]`).scrollWidth + 53}px`;
|
||||
}
|
||||
|
||||
setTranslationTarget(translationTarget) {
|
||||
|
|
|
@ -30,14 +30,20 @@
|
|||
|
||||
class ItemPaneHeader extends ItemPaneSectionElementBase {
|
||||
content = MozXULElement.parseXULToFragment(`
|
||||
<html:div class="title">
|
||||
<editable-text />
|
||||
<html:div class="head-container">
|
||||
<html:div class="title-head">
|
||||
<html:div class="title">
|
||||
<editable-text />
|
||||
</html:div>
|
||||
|
||||
<html:div class="creator-year"></html:div>
|
||||
|
||||
<html:div class="bib-entry"></html:div>
|
||||
</html:div>
|
||||
|
||||
<html:div class="custom-head"></html:div>
|
||||
</html:div>
|
||||
|
||||
<html:div class="creator-year" />
|
||||
|
||||
<html:div class="bib-entry" />
|
||||
|
||||
|
||||
<popupset>
|
||||
<menupopup class="secondary-popup">
|
||||
<menuitem data-l10n-id="text-action-copy" />
|
||||
|
@ -47,8 +53,6 @@
|
|||
</menu>
|
||||
</menupopup>
|
||||
</popupset>
|
||||
|
||||
<html:div class="custom-head"/>
|
||||
`, ['chrome://zotero/locale/zotero.dtd']);
|
||||
|
||||
_item = null;
|
||||
|
@ -68,8 +72,6 @@
|
|||
this._notifierID = Zotero.Notifier.registerObserver(this, ['item'], 'paneHeader');
|
||||
this._prefsObserverIDs = [
|
||||
Zotero.Prefs.registerObserver('itemPaneHeader', () => {
|
||||
// TEMP?: _forceRenderAll() doesn't do anything if the section is hidden, so un-hide first
|
||||
this.hidden = false;
|
||||
this._forceRenderAll();
|
||||
}),
|
||||
Zotero.Prefs.registerObserver('itemPaneHeader.bibEntry.style', () => this._forceRenderAll()),
|
||||
|
@ -196,15 +198,16 @@
|
|||
headerMode = 'title';
|
||||
}
|
||||
|
||||
if (headerMode === 'none') {
|
||||
this.hidden = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.hidden = false;
|
||||
this.title.hidden = true;
|
||||
this.creatorYear.hidden = true;
|
||||
this.bibEntry.hidden = true;
|
||||
|
||||
if (headerMode === 'none') {
|
||||
this.classList.add('no-title-head');
|
||||
return;
|
||||
}
|
||||
|
||||
this.classList.remove('no-title-head');
|
||||
|
||||
if (headerMode === 'bibEntry') {
|
||||
if (!Zotero.Styles.initialized()) {
|
||||
|
@ -379,6 +382,7 @@
|
|||
doc: document,
|
||||
append,
|
||||
});
|
||||
this.classList.toggle('has-custom-head', customHead.innerHTML);
|
||||
}
|
||||
}
|
||||
customElements.define("item-pane-header", ItemPaneHeader);
|
||||
|
|
|
@ -411,45 +411,3 @@ TODO: Replace with SVG
|
|||
background-color: Highlight;
|
||||
color: HighlightText;
|
||||
}
|
||||
|
||||
.split-menu-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.split-menu-button [anonid="button-image-and-text-box"] {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.split-menu-button [anonid="button-image"] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex-shrink: 0;
|
||||
margin-inline-end: 8px;
|
||||
}
|
||||
|
||||
.split-menu-button [anonid="button-text"] {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.split-menu-button [anonid="dropmarker-box"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.split-menu-button [anonid="dropmarker-separator"] {
|
||||
height: calc(100% - 5px);
|
||||
border-inline-start: 1px solid #aaa;
|
||||
margin: 0 2px 0 4px;
|
||||
}
|
||||
|
||||
.split-menu-button .split-menu-button-dropmarker {
|
||||
margin-inline: 5px;
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
@import "elements/quickSearchTextbox";
|
||||
@import "elements/richlistCheckbox";
|
||||
@import "elements/styleConfigurator";
|
||||
@import "elements/splitMenuButton";
|
||||
@import "elements/tagsBox";
|
||||
@import "elements/zoteroSearch";
|
||||
@import "elements/itemPaneHeader";
|
||||
|
|
|
@ -62,3 +62,7 @@
|
|||
{
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.feed-item-addTo-button {
|
||||
--split-button-icon-color: var(--accent-blue);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ item-message-pane {
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
align-self: stretch;
|
||||
gap: 6px;
|
||||
gap: 8px;
|
||||
padding: 6px 8px;
|
||||
background: var(--material-toolbar);
|
||||
border-bottom: var(--material-panedivider);
|
||||
|
|
|
@ -11,49 +11,118 @@ item-pane-header {
|
|||
overflow-y: auto;
|
||||
scrollbar-color: var(--color-scrollbar) var(--color-scrollbar-background);
|
||||
|
||||
.title {
|
||||
margin-top: calc(0px - var(--editable-text-padding-block));
|
||||
flex: 1 1 0;
|
||||
font-weight: 600;
|
||||
line-height: 1.333;
|
||||
|
||||
editable-text {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.creator-year {
|
||||
color: var(--fill-secondary);
|
||||
}
|
||||
|
||||
.bib-entry {
|
||||
line-height: 1.5;
|
||||
|
||||
&.loading {
|
||||
color: var(--fill-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
.creator-year, .bib-entry {
|
||||
// Set padding to match editable-text in tight mode, plus 1px for border
|
||||
padding-inline: calc(var(--editable-text-tight-padding-inline) + 1px);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.custom-head {
|
||||
.head-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-self: stretch;
|
||||
gap: 6px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
@include compact {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
button {
|
||||
height: 26px;
|
||||
margin: 0;
|
||||
flex-grow: 1;
|
||||
@include comfortable {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.title-head {
|
||||
align-self: stretch;
|
||||
|
||||
.title {
|
||||
margin-top: calc(0px - var(--editable-text-padding-block));
|
||||
flex: 1 1 0;
|
||||
font-weight: 600;
|
||||
line-height: 1.333;
|
||||
|
||||
editable-text {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.creator-year {
|
||||
color: var(--fill-secondary);
|
||||
}
|
||||
|
||||
.bib-entry {
|
||||
line-height: 1.5;
|
||||
|
||||
&.loading {
|
||||
color: var(--fill-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
.creator-year, .bib-entry {
|
||||
// Set padding to match editable-text in tight mode, plus 1px for border
|
||||
padding-inline: calc(var(--editable-text-tight-padding-inline) + 1px);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-head {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-self: stretch;
|
||||
gap: 8px;
|
||||
|
||||
@media (-moz-platform: macos) {
|
||||
// The extent of the button is about 2px wider than its optical width
|
||||
// need to compensate for that
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
button {
|
||||
// Allow the button to grow/shrink to fit the container
|
||||
width: 0;
|
||||
margin: 0;
|
||||
flex-grow: 1;
|
||||
|
||||
padding: 2px 6px;
|
||||
|
||||
@media (-moz-platform: macos) {
|
||||
height: 24px;
|
||||
padding: 3px 0px 1px 0px;
|
||||
|
||||
&:is(.split-menu-button) {
|
||||
padding: 3px 2px 1px 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.button-text {
|
||||
width: 0;
|
||||
flex-grow: 1;
|
||||
justify-content: center;
|
||||
|
||||
&::before {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
&:is(.no-shrink-button) {
|
||||
width: auto;
|
||||
flex-shrink: 0;
|
||||
|
||||
.button-text {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.no-title-head {
|
||||
&:not(.has-custom-head) {
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.title-head {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ note-editor {
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
align-self: stretch;
|
||||
gap: 6px;
|
||||
gap: 8px;
|
||||
padding: 6px 8px;
|
||||
background: var(--material-toolbar);
|
||||
border-bottom: var(--material-panedivider);
|
||||
|
|
50
scss/elements/_splitMenuButton.scss
Normal file
50
scss/elements/_splitMenuButton.scss
Normal file
|
@ -0,0 +1,50 @@
|
|||
.split-menu-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 0;
|
||||
gap: 6px;
|
||||
|
||||
& [anonid="button-image-and-text-box"] {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
// Allow the button to grow/shrink to fit the container
|
||||
width: 0;
|
||||
}
|
||||
|
||||
& [anonid="button-image"] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex-shrink: 0;
|
||||
margin-inline-end: 4px;
|
||||
color: var(--split-button-icon-color);
|
||||
fill: currentColor;
|
||||
-moz-context-properties: fill,fill-opacity;
|
||||
}
|
||||
|
||||
& [anonid="button-text"] {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
& [anonid="dropmarker-box"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
& [anonid="dropmarker-separator"] {
|
||||
height: calc(100% - 2px);
|
||||
border-inline-start: 1px solid var(--fill-quinary);
|
||||
}
|
||||
|
||||
& .split-menu-button-dropmarker {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
color: var(--fill-secondary);
|
||||
fill: currentColor;
|
||||
-moz-context-properties: fill,fill-opacity;
|
||||
}
|
||||
}
|
|
@ -12,6 +12,8 @@ menupopup {
|
|||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
border-radius: 4px;
|
||||
fill: currentColor;
|
||||
-moz-context-properties: fill,fill-opacity;
|
||||
&[_moz-menuactive="true"] {
|
||||
background: var(--fill-quinary);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
@mixin windows-form-element-base {
|
||||
appearance: none;
|
||||
padding: 0;
|
||||
border: solid 1px transparent;
|
||||
border: 1px solid transparent !important;
|
||||
border-radius: 3px;
|
||||
|
||||
background-origin: border-box;
|
||||
background-clip: padding-box, padding-box, border-box;
|
||||
// Overwrite default background color
|
||||
background-color: unset;
|
||||
background-color: unset !important;
|
||||
// Simulate linear-gradient border with border-radius using background-image
|
||||
|
||||
@include light-dark(--color-form-element-background, var(--color-background70), var(--fill-quinary));
|
||||
|
|
|
@ -66,7 +66,23 @@ describe("Item pane", function () {
|
|||
it("should be hidden when set to None mode", async function () {
|
||||
Zotero.Prefs.set('itemPaneHeader', 'none');
|
||||
await createDataObject('item', itemData);
|
||||
assert.isTrue(doc.querySelector('item-pane-header').hidden);
|
||||
assert.equal(doc.querySelector('item-pane-header').clientHeight, 0);
|
||||
});
|
||||
|
||||
it("should show custom header elements when set to None mode", async function () {
|
||||
Zotero.Prefs.set('itemPaneHeader', 'none');
|
||||
|
||||
// Use feed item toggle button as an example
|
||||
let feed = await createFeed();
|
||||
await selectLibrary(win, feed.libraryID);
|
||||
await waitForItemsLoad(win);
|
||||
|
||||
var item = await createDataObject('feedItem', { libraryID: feed.libraryID });
|
||||
await ZoteroPane.selectItem(item.id);
|
||||
let feedButton = ZoteroPane.itemPane._itemDetails.querySelector('.feed-item-toggleRead-button');
|
||||
assert.exists(feedButton);
|
||||
|
||||
await selectLibrary(win);
|
||||
});
|
||||
|
||||
it("should show title when set to Title mode", async function () {
|
||||
|
|
Loading…
Reference in a new issue