DEV: Convert ResponsiveTable to gjs (#30430)

This commit is contained in:
Jarek Radosz 2024-12-23 21:50:13 +01:00 committed by GitHub
parent e90a92b298
commit c6dd33cc06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 89 additions and 74 deletions

View File

@ -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("

View File

@ -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>
}

View File

@ -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>

View File

@ -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);
}
}
}