mirror of
https://github.com/discourse/discourse.git
synced 2025-03-13 14:15:30 +08:00
DEV: Convert ResponsiveTable to gjs (#30430)
This commit is contained in:
parent
e90a92b298
commit
c6dd33cc06
@ -67,7 +67,7 @@
|
||||
{{#if this.users}}
|
||||
<ResponsiveTable
|
||||
@className={{concat-class "users-list" this.query}}
|
||||
@aria-label={{this.title}}
|
||||
@ariaLabel={{this.title}}
|
||||
@style={{html-safe
|
||||
(concat
|
||||
"grid-template-columns: minmax(min-content, 2fr) repeat("
|
||||
|
@ -0,0 +1,88 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { fn } from "@ember/helper";
|
||||
import { on } from "@ember/modifier";
|
||||
import didUpdate from "@ember/render-modifiers/modifiers/did-update";
|
||||
import { modifier } from "ember-modifier";
|
||||
import concatClass from "discourse/helpers/concat-class";
|
||||
import onResize from "discourse/modifiers/on-resize";
|
||||
import { bind } from "discourse-common/utils/decorators";
|
||||
|
||||
export default class ResponsiveTable extends Component {
|
||||
lastScrollPosition = 0;
|
||||
ticking = false;
|
||||
table;
|
||||
topHorizontalScrollBar;
|
||||
fakeScrollContent;
|
||||
|
||||
setup = modifier((element) => {
|
||||
this.table = element.querySelector(".directory-table");
|
||||
this.topHorizontalScrollBar = element.querySelector(
|
||||
".directory-table-top-scroll"
|
||||
);
|
||||
this.fakeScrollContent = element.querySelector(
|
||||
".directory-table-top-scroll-fake-content"
|
||||
);
|
||||
|
||||
this.checkScroll();
|
||||
});
|
||||
|
||||
@bind
|
||||
checkScroll() {
|
||||
if (this.table.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.scrollWidth}px`;
|
||||
this.fakeScrollContent.style.height = "1px";
|
||||
}
|
||||
}
|
||||
|
||||
@bind
|
||||
replicateScroll(from, to) {
|
||||
this.lastScrollPosition = from?.scrollLeft;
|
||||
|
||||
if (!this.ticking) {
|
||||
window.requestAnimationFrame(() => {
|
||||
to.scrollLeft = this.lastScrollPosition;
|
||||
this.ticking = false;
|
||||
});
|
||||
|
||||
this.ticking = true;
|
||||
}
|
||||
}
|
||||
|
||||
<template>
|
||||
<div {{this.setup}} class="directory-table-container" ...attributes>
|
||||
<div
|
||||
{{on
|
||||
"scroll"
|
||||
(fn this.replicateScroll this.topHorizontalScrollBar this.table)
|
||||
}}
|
||||
class="directory-table-top-scroll"
|
||||
>
|
||||
<div class="directory-table-top-scroll-fake-content"></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
{{didUpdate this.checkScroll}}
|
||||
{{onResize this.checkScroll}}
|
||||
{{on
|
||||
"scroll"
|
||||
(fn this.replicateScroll this.table this.topHorizontalScrollBar)
|
||||
}}
|
||||
role="table"
|
||||
aria-label={{@ariaLabel}}
|
||||
style={{@style}}
|
||||
class={{concatClass "directory-table" @className}}
|
||||
>
|
||||
<div class="directory-table__header">
|
||||
{{yield to="header"}}
|
||||
</div>
|
||||
|
||||
<div class="directory-table__body">
|
||||
{{yield to="body"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
<div class="directory-table-container">
|
||||
<div class="directory-table-top-scroll" {{on "scroll" this.onTopScroll}}>
|
||||
<div class="directory-table-top-scroll-fake-content"></div>
|
||||
</div>
|
||||
<div
|
||||
class={{concat-class "directory-table" @className}}
|
||||
role="table"
|
||||
aria-label={{@ariaLabel}}
|
||||
style={{@style}}
|
||||
{{did-insert this.checkScroll}}
|
||||
{{did-update this.checkScroll}}
|
||||
{{on-resize this.checkScroll}}
|
||||
{{on "scroll" this.onBottomScroll}}
|
||||
>
|
||||
<div class="directory-table__header">
|
||||
{{yield to="header"}}
|
||||
</div>
|
||||
<div class="directory-table__body">
|
||||
{{yield to="body"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,51 +0,0 @@
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import Component from "@ember/component";
|
||||
import { bind } from "discourse-common/utils/decorators";
|
||||
|
||||
export default class ResponsiveTable extends Component {
|
||||
@tracked lastScrollPosition = 0;
|
||||
@tracked ticking = false;
|
||||
@tracked _table = document.querySelector(".directory-table");
|
||||
@tracked _topHorizontalScrollBar = document.querySelector(
|
||||
".directory-table-top-scroll"
|
||||
);
|
||||
|
||||
@bind
|
||||
checkScroll() {
|
||||
const _fakeScrollContent = document.querySelector(
|
||||
".directory-table-top-scroll-fake-content"
|
||||
);
|
||||
|
||||
if (this._table.getBoundingClientRect().bottom < window.innerHeight) {
|
||||
// Bottom of the table is visible. Hide the scrollbar
|
||||
_fakeScrollContent.style.height = 0;
|
||||
} else {
|
||||
_fakeScrollContent.style.width = `${this._table.scrollWidth}px`;
|
||||
_fakeScrollContent.style.height = "1px";
|
||||
}
|
||||
}
|
||||
|
||||
@bind
|
||||
onTopScroll() {
|
||||
this.onHorizontalScroll(this._topHorizontalScrollBar, this._table);
|
||||
}
|
||||
|
||||
@bind
|
||||
onBottomScroll() {
|
||||
this.onHorizontalScroll(this._table, this._topHorizontalScrollBar);
|
||||
}
|
||||
|
||||
@bind
|
||||
onHorizontalScroll(primary, replica) {
|
||||
this.set("lastScrollPosition", primary?.scrollLeft);
|
||||
|
||||
if (!this.ticking) {
|
||||
window.requestAnimationFrame(() => {
|
||||
replica.scrollLeft = this.lastScrollPosition;
|
||||
this.set("ticking", false);
|
||||
});
|
||||
|
||||
this.set("ticking", true);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user