Alyafeai commited on
Commit
67147ab
·
1 Parent(s): 633c620

Make and columns sticky

Browse files
Files changed (1) hide show
  1. frontend/leaderboard.html +128 -0
frontend/leaderboard.html CHANGED
@@ -78,6 +78,78 @@
78
  border-top: none !important;
79
  }
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  .dark .gridjs-head,
82
  .dark th.gridjs-th {
83
  background-color: #0f172a !important;
@@ -98,6 +170,8 @@
98
  table.gridjs-table {
99
  width: 100% !important;
100
  table-layout: fixed;
 
 
101
  }
102
 
103
  td.gridjs-td {
@@ -924,6 +998,11 @@
924
  }
925
  });
926
 
 
 
 
 
 
927
  if (window.lucide) lucide.createIcons();
928
  };
929
 
@@ -1318,6 +1397,53 @@
1318
 
1319
  window.applyFilters = applyFilters;
1320
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1321
  function applyFilters() {
1322
  if (!lbData.length) return;
1323
  const sVal = $('#searchInput').value.toLowerCase();
@@ -1375,6 +1501,7 @@
1375
 
1376
  // 5. Update Grid
1377
  grid.updateConfig({ data: filtered, columns: tableColumns }).forceRender();
 
1378
  $('#modelCounter').innerText = `${filtered.length} / ${lbData.length}`;
1379
  }
1380
 
@@ -1389,6 +1516,7 @@
1389
  td: 'bg-white dark:bg-darkcard text-slate-600 dark:text-slate-300 border-b border-slate-200 dark:border-slate-700 px-6 py-3'
1390
  }
1391
  }).render($('#table-wrapper'));
 
1392
  }
1393
 
1394
  function prepareColumns(data) {
 
78
  border-top: none !important;
79
  }
80
 
81
+ #table-wrapper .gridjs-th.sticky-rank-col,
82
+ #table-wrapper .gridjs-td.sticky-rank-col {
83
+ position: sticky !important;
84
+ left: 0 !important;
85
+ z-index: 32 !important;
86
+ box-shadow: 1px 0 0 rgba(148, 163, 184, 0.25);
87
+ }
88
+
89
+ #table-wrapper .gridjs-th.sticky-model-col,
90
+ #table-wrapper .gridjs-td.sticky-model-col {
91
+ position: sticky !important;
92
+ left: var(--sticky-model-left, 110px) !important;
93
+ z-index: 31 !important;
94
+ box-shadow: 1px 0 0 rgba(148, 163, 184, 0.25);
95
+ }
96
+
97
+ #table-wrapper .gridjs-th.sticky-rank-col,
98
+ #table-wrapper .gridjs-th.sticky-model-col {
99
+ z-index: 40 !important;
100
+ top: 0 !important;
101
+ }
102
+
103
+ #table-wrapper .gridjs-td.sticky-rank-col,
104
+ #table-wrapper .gridjs-td.sticky-model-col {
105
+ background: #fff !important;
106
+ }
107
+
108
+ .dark #table-wrapper .gridjs-td.sticky-rank-col,
109
+ .dark #table-wrapper .gridjs-td.sticky-model-col {
110
+ background: #1e293b !important;
111
+ box-shadow: 1px 0 0 rgba(71, 85, 105, 0.6);
112
+ }
113
+
114
+ .dark #table-wrapper .gridjs-th.sticky-rank-col,
115
+ .dark #table-wrapper .gridjs-th.sticky-model-col {
116
+ box-shadow: 1px 0 0 rgba(71, 85, 105, 0.6);
117
+ }
118
+
119
+ /* Fallback sticky behavior (covers async re-renders where classes may lag). */
120
+ #table-wrapper table.gridjs-table thead th:nth-child(1) {
121
+ position: sticky !important;
122
+ left: 0 !important;
123
+ top: 0 !important;
124
+ z-index: 46 !important;
125
+ background: #f1f5f9 !important;
126
+ }
127
+
128
+ #table-wrapper table.gridjs-table tbody td:nth-child(1) {
129
+ position: sticky !important;
130
+ left: 0 !important;
131
+ z-index: 30 !important;
132
+ }
133
+
134
+ #table-wrapper table.gridjs-table thead th:nth-child(2) {
135
+ position: sticky !important;
136
+ left: var(--sticky-model-left, 110px) !important;
137
+ top: 0 !important;
138
+ z-index: 45 !important;
139
+ background: #f1f5f9 !important;
140
+ }
141
+
142
+ #table-wrapper table.gridjs-table tbody td:nth-child(2) {
143
+ position: sticky !important;
144
+ left: var(--sticky-model-left, 110px) !important;
145
+ z-index: 29 !important;
146
+ }
147
+
148
+ .dark #table-wrapper table.gridjs-table thead th:nth-child(1),
149
+ .dark #table-wrapper table.gridjs-table thead th:nth-child(2) {
150
+ background: #0f172a !important;
151
+ }
152
+
153
  .dark .gridjs-head,
154
  .dark th.gridjs-th {
155
  background-color: #0f172a !important;
 
170
  table.gridjs-table {
171
  width: 100% !important;
172
  table-layout: fixed;
173
+ border-collapse: separate !important;
174
+ border-spacing: 0 !important;
175
  }
176
 
177
  td.gridjs-td {
 
998
  }
999
  });
1000
 
1001
+ if (!window.__stickyModelResizeBound) {
1002
+ window.addEventListener('resize', () => scheduleStickyApply());
1003
+ window.__stickyModelResizeBound = true;
1004
+ }
1005
+
1006
  if (window.lucide) lucide.createIcons();
1007
  };
1008
 
 
1397
 
1398
  window.applyFilters = applyFilters;
1399
 
1400
+ function applyStickyModelNameColumn() {
1401
+ const wrapper = $('#table-wrapper');
1402
+ if (!wrapper) return false;
1403
+ const table = wrapper.querySelector('table.gridjs-table');
1404
+ if (!table) return false;
1405
+
1406
+ const headers = [...table.querySelectorAll('thead th')];
1407
+ if (!headers.length) return false;
1408
+ const visibleCols = tableColumns.filter(c => !c.hidden).map(c => c.id);
1409
+ const rankIdx = visibleCols.indexOf("Rank");
1410
+ const modelIdx = visibleCols.indexOf("Model Name");
1411
+
1412
+ headers.forEach(th => th.classList.remove('sticky-rank-col', 'sticky-model-col'));
1413
+ table.querySelectorAll('tbody tr').forEach(tr => {
1414
+ [...tr.children].forEach(td => td.classList.remove('sticky-rank-col', 'sticky-model-col'));
1415
+ });
1416
+
1417
+ if (rankIdx >= 0 && headers[rankIdx]) {
1418
+ headers[rankIdx].classList.add('sticky-rank-col');
1419
+ table.querySelectorAll('tbody tr').forEach(tr => {
1420
+ if (tr.children[rankIdx]) tr.children[rankIdx].classList.add('sticky-rank-col');
1421
+ });
1422
+ }
1423
+
1424
+ const rankWidth = (rankIdx >= 0 && headers[rankIdx]) ? headers[rankIdx].getBoundingClientRect().width : 0;
1425
+ wrapper.style.setProperty('--sticky-model-left', `${Math.max(0, Math.round(rankWidth))}px`);
1426
+
1427
+ if (modelIdx >= 0 && headers[modelIdx]) {
1428
+ headers[modelIdx].classList.add('sticky-model-col');
1429
+ table.querySelectorAll('tbody tr').forEach(tr => {
1430
+ if (tr.children[modelIdx]) tr.children[modelIdx].classList.add('sticky-model-col');
1431
+ });
1432
+ }
1433
+ return true;
1434
+ }
1435
+
1436
+ function scheduleStickyApply(retries = 8) {
1437
+ let attempts = 0;
1438
+ const run = () => {
1439
+ const ok = applyStickyModelNameColumn();
1440
+ if (ok || attempts >= retries) return;
1441
+ attempts += 1;
1442
+ setTimeout(() => requestAnimationFrame(run), 40);
1443
+ };
1444
+ run();
1445
+ }
1446
+
1447
  function applyFilters() {
1448
  if (!lbData.length) return;
1449
  const sVal = $('#searchInput').value.toLowerCase();
 
1501
 
1502
  // 5. Update Grid
1503
  grid.updateConfig({ data: filtered, columns: tableColumns }).forceRender();
1504
+ scheduleStickyApply();
1505
  $('#modelCounter').innerText = `${filtered.length} / ${lbData.length}`;
1506
  }
1507
 
 
1516
  td: 'bg-white dark:bg-darkcard text-slate-600 dark:text-slate-300 border-b border-slate-200 dark:border-slate-700 px-6 py-3'
1517
  }
1518
  }).render($('#table-wrapper'));
1519
+ scheduleStickyApply();
1520
  }
1521
 
1522
  function prepareColumns(data) {