mirror of
https://github.com/discourse/discourse.git
synced 2025-06-06 23:07:28 +08:00
DEV: Convert ResponsiveTable to gjs (#30430)
This commit is contained in:
@ -67,7 +67,7 @@
|
|||||||
{{#if this.users}}
|
{{#if this.users}}
|
||||||
<ResponsiveTable
|
<ResponsiveTable
|
||||||
@className={{concat-class "users-list" this.query}}
|
@className={{concat-class "users-list" this.query}}
|
||||||
@aria-label={{this.title}}
|
@ariaLabel={{this.title}}
|
||||||
@style={{html-safe
|
@style={{html-safe
|
||||||
(concat
|
(concat
|
||||||
"grid-template-columns: minmax(min-content, 2fr) repeat("
|
"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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user