feat: simplify tables container by using native scrollbar styling and remove obsolete top scroll sync
This commit is contained in:
@@ -107,7 +107,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Logs Table -->
|
<!-- Logs Table -->
|
||||||
{{ ui::table_container_open(id="audit-table", has_top_scroll=true, max_height="68vh") }}
|
{{ ui::table_container_open(id="audit-table", max_height="68vh") }}
|
||||||
<table class="min-w-full divide-y divide-slate-800 text-left text-sm text-slate-300 relative">
|
<table class="min-w-full divide-y divide-slate-800 text-left text-sm text-slate-300 relative">
|
||||||
<thead class="shadow-[0_1px_0_0_rgba(255,255,255,0.05)]">
|
<thead class="shadow-[0_1px_0_0_rgba(255,255,255,0.05)]">
|
||||||
<tr class="text-xs font-bold text-slate-400 uppercase tracking-wider">
|
<tr class="text-xs font-bold text-slate-400 uppercase tracking-wider">
|
||||||
@@ -214,7 +214,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{{ ui::table_container_close(id="audit-table", has_top_scroll=true) }}
|
{{ ui::table_container_close(id="audit-table") }}
|
||||||
|
|
||||||
<!-- Footer Navigation -->
|
<!-- Footer Navigation -->
|
||||||
<div class="mt-6 text-center text-sm text-slate-400">
|
<div class="mt-6 text-center text-sm text-slate-400">
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- User List -->
|
<!-- User List -->
|
||||||
{{ ui::table_container_open(id="users-table", has_top_scroll=false, max_height="auto") }}
|
{{ ui::table_container_open(id="users-table", max_height="auto") }}
|
||||||
<table class="min-w-full divide-y divide-slate-800 text-left text-sm text-slate-300 relative">
|
<table class="min-w-full divide-y divide-slate-800 text-left text-sm text-slate-300 relative">
|
||||||
<thead class="shadow-[0_1px_0_0_rgba(255,255,255,0.05)]">
|
<thead class="shadow-[0_1px_0_0_rgba(255,255,255,0.05)]">
|
||||||
<tr class="text-xs font-bold text-slate-400 uppercase tracking-wider">
|
<tr class="text-xs font-bold text-slate-400 uppercase tracking-wider">
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{{ ui::table_container_close(id="users-table", has_top_scroll=false) }}
|
{{ ui::table_container_close(id="users-table") }}
|
||||||
|
|
||||||
<div class="mt-6 text-center text-sm text-slate-400">
|
<div class="mt-6 text-center text-sm text-slate-400">
|
||||||
<a href="/auth/password" class="font-medium text-sky-400 hover:underline">← Back to Account Settings</a>
|
<a href="/auth/password" class="font-medium text-sky-400 hover:underline">← Back to Account Settings</a>
|
||||||
|
|||||||
@@ -389,53 +389,13 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro table_container_open(id, has_top_scroll=true, max_height="68vh") %}
|
{% macro table_container_open(id, max_height="68vh") %}
|
||||||
{% if has_top_scroll %}
|
|
||||||
<!-- Top Horizontal Scrollbar (Synced) -->
|
|
||||||
<div id="{{ id }}-scrollbar-top" class="overflow-x-auto w-full scrollbar-thin mb-3 bg-[#1e293b]/20 border border-slate-900/50 rounded-xl py-1 px-2">
|
|
||||||
<div id="{{ id }}-scrollbar-top-inner" style="height: 1px;"></div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<!-- Table Container -->
|
<!-- Table Container -->
|
||||||
<div class="bg-[#1e293b]/40 backdrop-blur-xl border border-slate-900 rounded-3xl shadow-2xl mb-8 overflow-hidden">
|
<div class="bg-[#1e293b]/40 backdrop-blur-xl border border-slate-900 rounded-3xl shadow-2xl mb-8 overflow-hidden">
|
||||||
<div id="{{ id }}-container" class="overflow-auto scrollbar-thin rounded-[22px]" style="max-height: {{ max_height }};">
|
<div id="{{ id }}-container" class="overflow-auto scrollbar-thin rounded-[22px]" style="max-height: {{ max_height }};">
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro table_container_close(id, has_top_scroll=true) %}
|
{% macro table_container_close(id) %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>{% endmacro %}
|
||||||
|
|
||||||
{% if has_top_scroll %}
|
|
||||||
<script>
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const topScroll = document.getElementById('{{ id }}-scrollbar-top');
|
|
||||||
const tableContainer = document.getElementById('{{ id }}-container');
|
|
||||||
const topScrollInner = document.getElementById('{{ id }}-scrollbar-top-inner');
|
|
||||||
const table = tableContainer ? tableContainer.querySelector('table') : null;
|
|
||||||
|
|
||||||
if (topScroll && tableContainer && topScrollInner && table) {
|
|
||||||
const updateWidth = () => {
|
|
||||||
topScrollInner.style.width = table.scrollWidth + 'px';
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initialize width mapping
|
|
||||||
updateWidth();
|
|
||||||
|
|
||||||
// Observe both resizing of the table and changes to table layout
|
|
||||||
const resizeObserver = new ResizeObserver(() => updateWidth());
|
|
||||||
resizeObserver.observe(table);
|
|
||||||
|
|
||||||
// Sync scroll positions
|
|
||||||
topScroll.addEventListener('scroll', () => {
|
|
||||||
tableContainer.scrollLeft = topScroll.scrollLeft;
|
|
||||||
});
|
|
||||||
tableContainer.addEventListener('scroll', () => {
|
|
||||||
topScroll.scrollLeft = tableContainer.scrollLeft;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
{% endmacro %}
|
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -1,7 +1,7 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% import "components/macros.html" as ui %}
|
{% import "components/macros.html" as ui %}
|
||||||
|
|
||||||
{% block title %}Tables & Scroll Sync - Design System Wiki{% endblock %}
|
{% block title %}Tables - Design System Wiki{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="grow max-w-7xl mx-auto w-full px-4 sm:px-6 lg:px-8 py-10 flex flex-col lg:flex-row gap-8">
|
<div class="grow max-w-7xl mx-auto w-full px-4 sm:px-6 lg:px-8 py-10 flex flex-col lg:flex-row gap-8">
|
||||||
@@ -15,9 +15,9 @@
|
|||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="pb-6 border-b border-border">
|
<div class="pb-6 border-b border-border">
|
||||||
<span class="text-xs font-semibold text-indigo-400">Layout & Navigation</span>
|
<span class="text-xs font-semibold text-indigo-400">Layout & Navigation</span>
|
||||||
<h1 class="text-3xl font-extrabold text-slate-100 tracking-tight mt-1">Tables & Scroll Sync</h1>
|
<h1 class="text-3xl font-extrabold text-slate-100 tracking-tight mt-1">Tables</h1>
|
||||||
<p class="text-muted-foreground text-sm mt-2 leading-relaxed">
|
<p class="text-muted-foreground text-sm mt-2 leading-relaxed">
|
||||||
A standardized container macro for horizontal scroll synchronization and scrollbar-fitting layout. It resolves the common usability issue of unreachable scrollbars on wide tables.
|
A standardized container macro for table styling and scrollbar-fitting layout. It resolves common styling issues like corner clipping and header bleed-through.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<section class="space-y-4">
|
<section class="space-y-4">
|
||||||
<h2 class="text-lg font-bold text-slate-200">Container Showcase</h2>
|
<h2 class="text-lg font-bold text-slate-200">Container Showcase</h2>
|
||||||
<p class="text-xs text-muted-foreground">
|
<p class="text-xs text-muted-foreground">
|
||||||
The macro standardizes the background styling, shadows, rounded borders, vertical height bounds, sticky headers, and outputs a synced scrollbar clone that rests at the top of the table.
|
The macro standardizes the background styling, shadows, rounded borders, vertical height bounds, and sticky headers.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="border border-border rounded-3xl p-5 bg-secondary/10 space-y-4">
|
<div class="border border-border rounded-3xl p-5 bg-secondary/10 space-y-4">
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
<!-- Demo Viewport -->
|
<!-- Demo Viewport -->
|
||||||
<div id="table-sandbox" class="wiki-pane">
|
<div id="table-sandbox" class="wiki-pane">
|
||||||
{{ ui::table_container_open(id="docs-demo-table", has_top_scroll=true, max_height="250px") }}
|
{{ ui::table_container_open(id="docs-demo-table", max_height="250px") }}
|
||||||
<table class="min-w-full divide-y divide-slate-800 text-left text-xs text-slate-300 relative">
|
<table class="min-w-full divide-y divide-slate-800 text-left text-xs text-slate-300 relative">
|
||||||
<thead class="shadow-[0_1px_0_0_rgba(255,255,255,0.05)]">
|
<thead class="shadow-[0_1px_0_0_rgba(255,255,255,0.05)]">
|
||||||
<tr class="text-[10px] font-bold text-slate-400 uppercase tracking-wider">
|
<tr class="text-[10px] font-bold text-slate-400 uppercase tracking-wider">
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{{ ui::table_container_close(id="docs-demo-table", has_top_scroll=true) }}
|
{{ ui::table_container_close(id="docs-demo-table") }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Code Snippet Area -->
|
<!-- Code Snippet Area -->
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
</button>
|
</button>
|
||||||
<pre class="bg-popover p-4 rounded-xl border border-border overflow-x-auto text-[10px] text-sky-400 font-mono"><code>{{ "{%" }} import "components/macros.html" as ui {{ "%}" }}
|
<pre class="bg-popover p-4 rounded-xl border border-border overflow-x-auto text-[10px] text-sky-400 font-mono"><code>{{ "{%" }} import "components/macros.html" as ui {{ "%}" }}
|
||||||
|
|
||||||
{{ ui::table_container_open(id="my-custom-table", has_top_scroll=true, max_height="68vh") }}
|
{{ ui::table_container_open(id="my-custom-table", max_height="68vh") }}
|
||||||
<table class="min-w-full divide-y divide-slate-800 text-left text-sm text-slate-300 relative">
|
<table class="min-w-full divide-y divide-slate-800 text-left text-sm text-slate-300 relative">
|
||||||
<thead class="shadow-[0_1px_0_0_rgba(255,255,255,0.05)]">
|
<thead class="shadow-[0_1px_0_0_rgba(255,255,255,0.05)]">
|
||||||
<tr class="text-xs font-bold text-slate-400 uppercase tracking-wider">
|
<tr class="text-xs font-bold text-slate-400 uppercase tracking-wider">
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{{ ui::table_container_close(id="my-custom-table", has_top_scroll=true) }}</code></pre>
|
{{ ui::table_container_close(id="my-custom-table") }}</code></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -125,9 +125,9 @@
|
|||||||
<div class="border border-border rounded-3xl p-6 bg-secondary/10 space-y-4">
|
<div class="border border-border rounded-3xl p-6 bg-secondary/10 space-y-4">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<h4 class="text-xs font-bold text-indigo-400 uppercase tracking-wider">Top Scroll Sync Logic</h4>
|
<h4 class="text-xs font-bold text-indigo-400 uppercase tracking-wider">Stylized Container Wrapper</h4>
|
||||||
<p class="text-xs text-muted-foreground leading-relaxed">
|
<p class="text-xs text-muted-foreground leading-relaxed">
|
||||||
Since HTML natively positions horizontal scrollbars only at the bottom of overflow elements, the component generates a custom dummy scroll container at the top of the table. A Javascript listener observes layout resizing and syncs the horizontal offsets of both the top scroll track and the main table scroll track dynamically.
|
Tables are automatically styled with rounded-3xl corners and background styling. The table container is scrollable, displaying a native horizontal or vertical scrollbar as needed.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
|
|||||||
Reference in New Issue
Block a user