diff --git a/chrome/content/zotero/components/virtualized-table.jsx b/chrome/content/zotero/components/virtualized-table.jsx
index 4f64a5116a..ef73f382fb 100644
--- a/chrome/content/zotero/components/virtualized-table.jsx
+++ b/chrome/content/zotero/components/virtualized-table.jsx
@@ -36,7 +36,7 @@ const TYPING_TIMEOUT = 1000;
const MINIMUM_ROW_HEIGHT = 20; // px
const RESIZER_WIDTH = 5; // px
const COLUMN_MIN_WIDTH = 20;
-const COLUMN_PADDING = 10; // N.B. MUST BE INLINE WITH CSS!!!
+const COLUMN_PADDING = 16; // N.B. MUST BE INLINE WITH CSS!!!
const noop = () => 0;
@@ -414,6 +414,7 @@ class VirtualizedTable extends React.Component {
staticColumns: PropTypes.bool,
// Used for initial column widths calculation
containerWidth: PropTypes.number,
+ firstColumnExtraWidth: PropTypes.number,
// Internal windowed-list ref
treeboxRef: PropTypes.func,
@@ -848,8 +849,8 @@ class VirtualizedTable extends React.Component {
offset += resizingRect.width;
}
const widthSum = aRect.width + bRect.width;
- const aSpacingOffset = (aColumn.minWidth ? aColumn.minWidth : COLUMN_MIN_WIDTH) + COLUMN_PADDING;
- const bSpacingOffset = (bColumn.minWidth ? bColumn.minWidth : COLUMN_MIN_WIDTH) + COLUMN_PADDING;
+ const aSpacingOffset = (aColumn.minWidth ? aColumn.minWidth : COLUMN_MIN_WIDTH) + (aColumn.noPadding ? 0 : COLUMN_PADDING);
+ const bSpacingOffset = (bColumn.minWidth ? bColumn.minWidth : COLUMN_MIN_WIDTH) + (bColumn.noPadding ? 0 : COLUMN_PADDING);
const aColumnWidth = Math.min(widthSum - bSpacingOffset, Math.max(aSpacingOffset, event.clientX - (RESIZER_WIDTH / 2) - offset));
const bColumnWidth = widthSum - aColumnWidth;
let onResizeData = {};
@@ -1425,6 +1426,12 @@ var Columns = class {
if (column.type) {
column.className += ` cell-${column.type}`;
}
+ if (column.fixedWidth) {
+ column.originalWidth = column.width;
+ }
+ if (column.staticWidth) {
+ column.originalMinWidth = column.minWidth || 20;
+ }
columns.push(column);
}
// Sort columns by their `ordinal` field
@@ -1456,6 +1463,7 @@ var Columns = class {
// Storing back persist settings to account for legacy upgrades
this._storePrefs(columnsSettings);
+ this._adjustColumnWidths();
// Set column width CSS rules
this.onResize(columnWidths);
// Whew, all this just to get a list of columns
@@ -1520,6 +1528,24 @@ var Columns = class {
this._virtualizedTable.props.storeColumnPrefs(prefs);
}
+ _adjustColumnWidths = () => {
+ if (!this._virtualizedTable.props.firstColumnExtraWidth) {
+ return;
+ }
+
+ const extraWidth = this._virtualizedTable.props.firstColumnExtraWidth;
+ this._columns.filter(c => !c.hidden).forEach((column, index) => {
+ const isFirstColumn = index === 0;
+ if (column.fixedWidth) {
+ column.width = isFirstColumn ? parseInt(column.originalWidth) + extraWidth : column.originalWidth;
+ }
+ if (column.staticWidth) {
+ column.minWidth = isFirstColumn ? (column.originalMinWidth ?? 20) + extraWidth : column.originalMinWidth;
+ column.width = isFirstColumn ? Math.max(parseInt(column.width) ?? 0, column.minWidth) : column.width;
+ }
+ });
+ };
+
/**
* Programatically sets the injected CSS width rules for each column.
* This is necessary for performance reasons
@@ -1530,8 +1556,7 @@ var Columns = class {
if (storePrefs) {
var prefs = this._getPrefs();
}
- const header = document.querySelector(`#${this._styleKey} .virtualized-table-header`);
- const headerWidth = header ? header.getBoundingClientRect().width : 300;
+
for (let [dataKey, width] of Object.entries(columnWidths)) {
if (typeof dataKey == "number") {
dataKey = this._columns[dataKey].dataKey;
@@ -1569,6 +1594,10 @@ var Columns = class {
if (a.ordinal == b.ordinal) return a == column ? -1 : 1;
return a.ordinal - b.ordinal;
});
+
+ this._adjustColumnWidths();
+ this.onResize(Object.fromEntries(this._columns.map(c => [c.dataKey, c.width])));
+
let prefs = this._getPrefs();
// reassign columns their ordinal values and set the prefs
this._columns.forEach((column, index) => {
@@ -1596,6 +1625,8 @@ var Columns = class {
}
}
this._columns.sort((a, b) => a.ordinal - b.ordinal);
+ this._adjustColumnWidths();
+ this.onResize(Object.fromEntries(this._columns.map(c => [c.dataKey, c.width])));
this._storePrefs(prefs);
this._updateVirtualizedTable();
}
@@ -1608,6 +1639,8 @@ var Columns = class {
if (prefs[column.dataKey]) {
prefs[column.dataKey].hidden = column.hidden;
}
+ this._adjustColumnWidths();
+ this.onResize(Object.fromEntries(this._columns.map(c => [c.dataKey, c.width])));
this._storePrefs(prefs);
this._updateVirtualizedTable();
}
diff --git a/chrome/content/zotero/itemTree.jsx b/chrome/content/zotero/itemTree.jsx
index 9f325bdae7..6f3cae3854 100644
--- a/chrome/content/zotero/itemTree.jsx
+++ b/chrome/content/zotero/itemTree.jsx
@@ -985,6 +985,7 @@ var ItemTree = class ItemTree extends LibraryTree {
storeColumnPrefs: this._storeColumnPrefs,
getDefaultColumnOrder: this._getDefaultColumnOrder,
containerWidth: this.domEl.clientWidth,
+ firstColumnExtraWidth: 28, // 16px for twisty + 16px for icon - 8px column padding + 4px margin
multiSelect: true,
@@ -2720,6 +2721,10 @@ var ItemTree = class ItemTree extends LibraryTree {
}
}
+ if (column.noPadding) {
+ cell.classList.add('no-padding');
+ }
+
if (isFirstColumn) {
// Add depth indent, twisty and icon
const depth = this.getLevel(index);
@@ -3163,7 +3168,7 @@ var ItemTree = class ItemTree extends LibraryTree {
}
this._columns.push(column);
}
-
+
return this._columns.sort((a, b) => a.ordinal - b.ordinal);
}
diff --git a/chrome/content/zotero/itemTreeColumns.jsx b/chrome/content/zotero/itemTreeColumns.jsx
index 5a9d8ef165..7978e9cf9c 100644
--- a/chrome/content/zotero/itemTreeColumns.jsx
+++ b/chrome/content/zotero/itemTreeColumns.jsx
@@ -40,6 +40,7 @@ const Icons = require('components/icons');
* @property {string} [width] - A column width instead of flex ratio. See above.
* @property {boolean} [fixedWidth] - Default: false. Set to true to disable column resizing
* @property {boolean} [staticWidth] - Default: false. Set to true to prevent columns from changing width when the width of the tree increases or decreases
+ * @property {boolean} [noPadding] - Set to true for columns with padding disabled in stylesheet
* @property {number} [minWidth] - Override the default [20px] column min-width for resizing
* @property {React.Component} [iconLabel] - Set an Icon label instead of a text-based one
* @property {string} [iconPath] - Set an Icon path, overrides {iconLabel}
@@ -337,7 +338,8 @@ const COLUMNS = [
label: "zotero.tabs.attachments.label",
iconLabel: ,
fixedWidth: true,
- width: "16",
+ width: "32",
+ noPadding: true,
zoteroPersist: ["hidden", "sortDirection"]
},
{
@@ -346,9 +348,10 @@ const COLUMNS = [
showInColumnPicker: true,
label: "zotero.tabs.notes.label",
iconLabel: ,
- width: "14",
- minWidth: 14,
+ width: "26",
+ minWidth: 26,
staticWidth: true,
+ noPadding: true,
zoteroPersist: ["width", "hidden", "sortDirection"]
},
{
diff --git a/scss/components/_item-tree.scss b/scss/components/_item-tree.scss
index 83f356cf9a..848ce1a576 100644
--- a/scss/components/_item-tree.scss
+++ b/scss/components/_item-tree.scss
@@ -21,6 +21,16 @@
padding-inline-end: calc(8px + var(--scrollbar-width, 0px));
box-sizing: border-box;
+ .cell.hasAttachment,
+ .cell.numNotes {
+ padding: 0;
+ text-align: center;
+
+ &.first-column {
+ padding-inline-start: 32px;
+ }
+ }
+
.first-column {
&::before {
content: "";
@@ -149,19 +159,35 @@
margin-inline-start: 3px;
}
}
+
+ .cell.no-padding {
+ padding: 0;
+ }
.cell.hasAttachment {
- box-sizing: content-box;
- // Don't show ellipsis
text-overflow: unset;
+ align-items: center;
+ display: flex;
+ justify-content: center;
+
+ .cell-text {
+ text-overflow: unset;
+ align-items: center;
+ display: flex;
+ justify-content: center;
+ }
.icon-missing-file {
opacity: 0.4;
}
}
- .cell.numNotes {
+ .numNotes, .hasAttachment {
text-align: center;
+
+ .cell-text {
+ text-align: center;
+ }
}
}
}
diff --git a/scss/components/_virtualized-table.scss b/scss/components/_virtualized-table.scss
index 950d1a968a..73a7584bf4 100644
--- a/scss/components/_virtualized-table.scss
+++ b/scss/components/_virtualized-table.scss
@@ -71,7 +71,9 @@
overflow: hidden;
&:not(:first-child) {
- margin-inline-start: 4px;
+ @include state(".cell.first-column:not(.hasAttachment)") {
+ margin-inline-start: 4px;
+ }
}
}