Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 92 additions & 2 deletions assets/sass/helpers.sass
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

.is-hero-logo
+logo(60%, 75%)

.is-footer-logo
+logo(40%, 75%)

Expand Down Expand Up @@ -62,6 +62,7 @@ hr.color
+touch
margin-right: 0.5rem


.content
.img
&:hover
Expand All @@ -72,11 +73,100 @@ hr.color
display: block
overflow-x: auto
white-space: nowrap

.is-page
display: flex
flex-direction: column
min-height: 100vh

.is-main
flex: 1


// ---- NEW TABLE MODAL + WRAPPER STYLES ----

.table-expanded
position: fixed
top: 5vh
left: 5vw
width: 90vw
height: 90vh
background: white
z-index: 9999
overflow: auto
padding: 1.5rem
white-space: normal
border-radius: 6px
box-shadow: 0 0 20px rgba(0,0,0,0.08)

table
width: 100%
table-layout: auto
white-space: normal
border-collapse: collapse

th, td
border: 1px solid rgba(0,0,0,0.08)
padding: 0.5rem 0.75rem
vertical-align: top

// ---- NEW FIXED CLOSE BUTTON ----
.table-close-btn
position: sticky // keeps button visible during scroll
top: 0.5rem
float: right
margin-bottom: 1rem
background: rgba(255,255,255,0.9)
border: 1px solid rgba(0,0,0,0.12)
padding: 0.35rem 0.5rem
border-radius: 4px
font-size: 1rem
cursor: pointer
box-shadow: 0 2px 6px rgba(0,0,0,0.06)
z-index: 10000

.table-close-btn:focus
outline: none
box-shadow: 0 0 0 3px rgba(0,0,0,0.06)


// ---- OVERLAY ----

.table-modal-overlay
position: fixed
top: 0
left: 0
width: 100vw
height: 100vh
background: rgba(255,255,255,0.35)
-webkit-backdrop-filter: blur(6px)
backdrop-filter: blur(6px)
z-index: 10


// ---- TABLE LIST PAGE WRAPPING ----

.table-wrapper
position: relative
margin-bottom: 1.25rem

.table-scroll
overflow-x: auto
-webkit-overflow-scrolling: touch

.table-enlarge-btn
position: absolute
top: 0.5rem
right: 0.5rem
background: rgba(0,0,0,0.6)
color: white
border: none
padding: 0.35rem 0.5rem
border-radius: 3px
cursor: pointer
font-size: 0.85rem
z-index: 2

.table-enlarge-btn:focus
outline: none
box-shadow: 0 0 0 2px rgba(0,0,0,0.12)
3 changes: 2 additions & 1 deletion layouts/partials/javascript.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@
function load() { if (window.location.hash) shiftWindow(); }

console.log("OK");
</script>
</script>
<script src="/js/table-popout.js"></script>
123 changes: 123 additions & 0 deletions static/js/table-popout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
document.addEventListener("DOMContentLoaded", function () {
const tables = document.querySelectorAll(".content table");
if (!tables.length) return;

tables.forEach(function (table) {
if (table.closest(".table-wrapper")) return;

const wrapper = document.createElement("div");
wrapper.className = "table-wrapper";

const scroll = document.createElement("div");
scroll.className = "table-scroll";

const btn = document.createElement("button");
btn.className = "table-enlarge-btn";
btn.type = "button";
btn.title = "Enlarge table";
btn.innerText = "⤢";

table.parentNode.insertBefore(wrapper, table);
wrapper.appendChild(scroll);
scroll.appendChild(table);
wrapper.appendChild(btn);

btn.addEventListener("click", function () {
openTableModal(table);
});
});

function openTableModal(table) {
const modal = document.createElement("div");
modal.className = "table-expanded";

// overlay to blur background and intercept clicks
const overlay = document.createElement("div");
overlay.className = "table-modal-overlay";

const closeBtn = document.createElement("button");
closeBtn.type = "button";
closeBtn.title = "Close";
closeBtn.innerText = "✕";
closeBtn.className = "table-close-btn";

const cloned = table.cloneNode(true);
cloned.style.width = "100%";
cloned.style.display = "table";
cloned.style.tableLayout = "auto";
cloned.style.whiteSpace = "normal";
cloned.style.borderCollapse = "collapse";

try {
const comp = window.getComputedStyle(table);
if (comp) {
if (comp.fontSize) cloned.style.fontSize = comp.fontSize;
if (comp.fontWeight) cloned.style.fontWeight = comp.fontWeight;
if (comp.fontFamily) cloned.style.fontFamily = comp.fontFamily;
if (comp.color) cloned.style.color = comp.color;
}

const srcCell = table.querySelector("th, td");
const tgtCells = cloned.querySelectorAll("th, td");
if (srcCell && tgtCells.length) {
const cellStyle = window.getComputedStyle(srcCell);
tgtCells.forEach(function (c) {
if (cellStyle.borderTopWidth)
c.style.borderTop =
cellStyle.borderTopWidth +
" " +
cellStyle.borderTopStyle +
" " +
cellStyle.borderTopColor;
if (cellStyle.borderRightWidth)
c.style.borderRight =
cellStyle.borderRightWidth +
" " +
cellStyle.borderRightStyle +
" " +
cellStyle.borderRightColor;
if (cellStyle.borderBottomWidth)
c.style.borderBottom =
cellStyle.borderBottomWidth +
" " +
cellStyle.borderBottomStyle +
" " +
cellStyle.borderBottomColor;
if (cellStyle.borderLeftWidth)
c.style.borderLeft =
cellStyle.borderLeftWidth +
" " +
cellStyle.borderLeftStyle +
" " +
cellStyle.borderLeftColor;
if (cellStyle.padding) c.style.padding = cellStyle.padding;
});
}
} catch (e) {
// ignore
}

modal.appendChild(closeBtn);
modal.appendChild(cloned);
// append overlay then modal so overlay is below modal
document.body.appendChild(overlay);
document.body.appendChild(modal);

function close() {
if (modal && modal.parentNode) modal.parentNode.removeChild(modal);
if (overlay && overlay.parentNode)
overlay.parentNode.removeChild(overlay);
document.removeEventListener("keydown", onKey);
}

closeBtn.addEventListener("click", close);
// clicking overlay also closes modal
overlay.addEventListener("click", close);

function onKey(e) {
if (e.key === "Escape") close();
}

document.addEventListener("keydown", onKey);
}
});