mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
UX: Horizontal scroll bar on top of user directory (when needed) (#13553)
This commit is contained in:
parent
7d0d13c32e
commit
d03aee4642
@ -2,16 +2,103 @@ import Component from "@ember/component";
|
|||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: ["directory-table-container"],
|
lastScrollPosition: 0,
|
||||||
|
ticking: false,
|
||||||
|
_topHorizontalScrollBar: null,
|
||||||
|
_tableContainer: null,
|
||||||
|
_table: null,
|
||||||
|
_fakeScrollContent: null,
|
||||||
|
|
||||||
|
didInsertElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
this.setProperties({
|
||||||
|
_tableContainer: this.element.querySelector(".directory-table-container"),
|
||||||
|
_topHorizontalScrollBar: this.element.querySelector(
|
||||||
|
".directory-table-top-scroll"
|
||||||
|
),
|
||||||
|
_fakeScrollContent: this.element.querySelector(
|
||||||
|
".directory-table-top-scroll-fake-content"
|
||||||
|
),
|
||||||
|
_table: this.element.querySelector(".directory-table"),
|
||||||
|
});
|
||||||
|
|
||||||
|
this._tableContainer.addEventListener("scroll", this.onBottomScroll);
|
||||||
|
this._topHorizontalScrollBar.addEventListener("scroll", this.onTopScroll);
|
||||||
|
|
||||||
|
// Set active header might have already scrolled the _tableContainer.
|
||||||
|
// Call onHorizontalScroll manually to scroll the _topHorizontalScrollBar
|
||||||
|
this.onResize();
|
||||||
|
this.onHorizontalScroll(this._tableContainer, this._topHorizontalScrollBar);
|
||||||
|
window.addEventListener("resize", this.onResize);
|
||||||
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
|
onResize() {
|
||||||
|
if (
|
||||||
|
this._tableContainer.getBoundingClientRect().bottom < window.innerHeight
|
||||||
|
) {
|
||||||
|
// Bottom of the table is visible. Hide the scrollbar
|
||||||
|
this._fakeScrollContent.style.height = 0;
|
||||||
|
} else {
|
||||||
|
this._fakeScrollContent.style.width = `${this._table.offsetWidth}px`;
|
||||||
|
this._fakeScrollContent.style.height = "1px";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
|
onTopScroll() {
|
||||||
|
this.onHorizontalScroll(this._topHorizontalScrollBar, this._tableContainer);
|
||||||
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
|
onBottomScroll() {
|
||||||
|
this.onHorizontalScroll(this._tableContainer, this._topHorizontalScrollBar);
|
||||||
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
|
onHorizontalScroll(primary, replica) {
|
||||||
|
if (this.lastScrollPosition === primary.scrollLeft) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set("lastScrollPosition", primary.scrollLeft);
|
||||||
|
|
||||||
|
if (!this.ticking) {
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
replica.scrollLeft = this.lastScrollPosition;
|
||||||
|
this.set("ticking", false);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.set("ticking", true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
willDestoryElement() {
|
||||||
|
this._tableContainer.removeEventListener("scroll", this.onBottomScroll);
|
||||||
|
this._topHorizontalScrollBar.removeEventListener(
|
||||||
|
"scroll",
|
||||||
|
this.onTopScroll
|
||||||
|
);
|
||||||
|
window.removeEventListener("resize", this.onResize);
|
||||||
|
},
|
||||||
|
|
||||||
@action
|
@action
|
||||||
setActiveHeader(header) {
|
setActiveHeader(header) {
|
||||||
// After render, scroll table left to ensure the order by column is visible
|
// After render, scroll table left to ensure the order by column is visible
|
||||||
|
if (!this._tableContainer) {
|
||||||
|
this.set(
|
||||||
|
"_tableContainer",
|
||||||
|
document.querySelector(".directory-table-container")
|
||||||
|
);
|
||||||
|
}
|
||||||
const scrollPixels =
|
const scrollPixels =
|
||||||
header.offsetLeft + header.offsetWidth + 10 - this.element.offsetWidth;
|
header.offsetLeft +
|
||||||
|
header.offsetWidth +
|
||||||
|
10 -
|
||||||
|
this._tableContainer.offsetWidth;
|
||||||
|
|
||||||
if (scrollPixels > 0) {
|
if (scrollPixels > 0) {
|
||||||
this.element.scrollLeft = scrollPixels;
|
this._tableContainer.scrollLeft = scrollPixels;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,25 +1,31 @@
|
|||||||
<table>
|
<div class="directory-table-top-scroll">
|
||||||
<thead>
|
<div class="directory-table-top-scroll-fake-content"></div>
|
||||||
{{table-header-toggle field="username" order=order asc=asc}}
|
</div>
|
||||||
{{#each columns as |column|}}
|
|
||||||
{{table-header-toggle
|
|
||||||
field=column.name
|
|
||||||
icon=column.icon
|
|
||||||
order=order
|
|
||||||
asc=asc
|
|
||||||
automatic=(directory-column-is-automatic column=column)
|
|
||||||
translated=column.user_field_id
|
|
||||||
onActiveRender=setActiveHeader
|
|
||||||
}}
|
|
||||||
{{/each}}
|
|
||||||
|
|
||||||
{{#if showTimeRead}}
|
<div class="directory-table-container">
|
||||||
<th>{{i18n "directory.time_read"}}</th>
|
<table class="directory-table">
|
||||||
{{/if}}
|
<thead>
|
||||||
</thead>
|
{{table-header-toggle field="username" order=order asc=asc}}
|
||||||
<tbody>
|
{{#each columns as |column|}}
|
||||||
{{#each items as |item|}}
|
{{table-header-toggle
|
||||||
{{directory-item item=item columns=columns showTimeRead=showTimeRead}}
|
field=column.name
|
||||||
{{/each}}
|
icon=column.icon
|
||||||
</tbody>
|
order=order
|
||||||
</table>
|
asc=asc
|
||||||
|
automatic=(directory-column-is-automatic column=column)
|
||||||
|
translated=column.user_field_id
|
||||||
|
onActiveRender=setActiveHeader
|
||||||
|
}}
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
|
{{#if showTimeRead}}
|
||||||
|
<th>{{i18n "directory.time_read"}}</th>
|
||||||
|
{{/if}}
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#each items as |item|}}
|
||||||
|
{{directory-item item=item columns=columns showTimeRead=showTimeRead}}
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.directory-table-top-scroll {
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.open-edit-columns-btn {
|
.open-edit-columns-btn {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
padding: 0.45em 0.8em;
|
padding: 0.45em 0.8em;
|
||||||
|
Loading…
Reference in New Issue
Block a user