Wrap each popover menu and give it a caller-named id
CI / full-gate (push) Successful in 2m43s

This commit is contained in:
2026-08-05 01:58:11 +02:00
parent 5d9bdebf59
commit cfeee10fa8
12 changed files with 99 additions and 58 deletions
+10 -2
View File
@@ -3,6 +3,8 @@
Zero-JS (sort = links, select highlight = CSS).
Config:
caption?, selectable?, actions? sr-only caption; toggle the check / kebab columns
actionsId? id stem for the row-action menus (default `row-actions`);
name it when two tables share a page
columns: { label, sortable?, sort?: "asc"|"desc", href?, className? }[]
rows: { name?, cells: Cell[], actions?: Action[] }[]
Cell ∈ string | { text, className? } | { user:{name,initials} } | { rowHeader:{text,href?} } | { badge:{tone,label} } | { html, className? }
@@ -17,6 +19,7 @@
const columns = locals.columns || [];
const rows = locals.rows || [];
const emptyText = locals.emptyText || t("table.empty"); // shown when a table that has columns has no rows
const actionsId = locals.actionsId || "row-actions";
-%>
<div class="table-wrap">
<table class="table">
@@ -44,7 +47,7 @@
<% if (rows.length === 0 && columns.length) { -%>
<tr><td class="table-empty" colspan="<%= columns.length + (selectable ? 1 : 0) + (withActions ? 1 : 0) %>"><%= emptyText %></td></tr>
<% } -%>
<% rows.forEach((row) => { -%>
<% rows.forEach((row, i) => { -%>
<tr>
<% if (selectable) { -%>
<td class="col-check"><input type="checkbox" class="row-select" aria-label="<%= t("table.select", { name: row.name || t("table.row") }) %>"></td>
@@ -67,9 +70,14 @@
<% if (withActions) { -%>
<% if ((row.actions || []).length) { -%>
<td class="col-actions"><%- include("menu", {
id: `${actionsId}-${i + 1}`,
kebab: true,
trigger: { class: "", icon: "i-kebab", label: t("table.rowActions", { name: row.name || t("table.row") }) },
items: row.actions.flatMap((a) => (a.separatorBefore ? [{ sep: true }, a] : [a])),
// Mapped field by field, not spread: an Action and a menu Item are separate shapes.
items: row.actions.flatMap((a) => {
const item = { danger: a.danger, href: a.href, icon: a.icon, label: a.label };
return a.separatorBefore ? [{ sep: true }, item] : [item];
}),
}) %></td>
<% } else { -%>
<td class="col-actions"></td>