You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2026/08/28 16:42:13 UTC
(juneau) branch master updated: Table Toolbar: caret alignment, italic placeholder, vendor margin override, and staleness/refresh pairing (WAVE-0011: TODO-J0450, TODO-J0457)
This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new 77bdaa8c6d Table Toolbar: caret alignment, italic placeholder, vendor margin override, and staleness/refresh pairing (WAVE-0011: TODO-J0450, TODO-J0457)
77bdaa8c6d is described below
commit 77bdaa8c6d6f5225db485bf62782b57bcf060e07
Author: James Bognar <ja...@apache.org>
AuthorDate: Fri Aug 28 12:42:07 2026 -0400
Table Toolbar: caret alignment, italic placeholder, vendor margin override, and staleness/refresh pairing (WAVE-0011: TODO-J0450, TODO-J0457)
---
.../org/apache/juneau/views/juneau-views.css | 47 +++++++++++++++++++++-
.../org/apache/juneau/views/juneau-views.js | 10 ++++-
.../server/views/TablePolling_Wiring_Test.java | 2 +-
3 files changed, 54 insertions(+), 5 deletions(-)
diff --git a/juneau-rest/juneau-rest-server-views/src/main/resources/org/apache/juneau/views/juneau-views.css b/juneau-rest/juneau-rest-server-views/src/main/resources/org/apache/juneau/views/juneau-views.css
index 03c05a167a..d7a156ed5d 100644
--- a/juneau-rest/juneau-rest-server-views/src/main/resources/org/apache/juneau/views/juneau-views.css
+++ b/juneau-rest/juneau-rest-server-views/src/main/resources/org/apache/juneau/views/juneau-views.css
@@ -688,6 +688,16 @@ table.dataTable thead .sorting_desc_disabled:after {
.dataTables_wrapper, .dt-container { min-width: 0; }
.juneau-view-table-scroll { overflow-x: auto; min-width: 0; }
+/*
+ * DataTables 2.1.8 pins an unowned .75em vertical margin on this row (Juneau vendors nothing here - each
+ * consumer supplies its own copy). Reclaiming it makes both edges Juneau's own decision instead of the
+ * vendor's: the top edge collapses against the toolbar row's own bottom margin (already this same step), and
+ * the bottom edge would otherwise fall through to whatever padding a host theme happens to supply. Narrow
+ * selector at specificity (0,3,0) beats the vendor's (0,2,2) on class count alone, so no !important and no
+ * stylesheet-order dependence. A DataTables version bump should re-check this margin still exists to neutralize.
+ */
+.dt-container > .dt-layout-row.dt-layout-table { margin: 0 0 var(--jc-space-2); }
+
/*
* The 10.0 one-overflow-contract half: the two scroll boxes above are unchanged, but cell CONTENT now CLIPS with an
* ellipsis instead of wrapping - the SAME policy on both DataTables generations, so a table no longer changes shape
@@ -777,6 +787,15 @@ table.dataTable thead .sorting_desc_disabled:after {
.juneau-view-pagingpill-info { white-space: nowrap; font-family: inherit; }
+/* Centring box for the baseline-seated inline SVG - without this the 12px glyph rides high against the
+ "n-n of n" range text beside it, since only the child svg (below) is sized and the span itself has no
+ display/vertical-align rule. Verbatim shape of .juneau-view-paging-double above: no height here, since
+ height is a checked ChromeScale property on this glyph family and inline-flex + centred items needs none. */
+.juneau-view-pagingpill-caret {
+ display: inline-flex;
+ align-items: center;
+}
+
.juneau-view-pagingpill-caret svg { width: var(--jc-chrome-glyph-size-small); height: var(--jc-chrome-glyph-size-small); fill: currentColor; }
/* The popup itself - absolutely positioned below the menu button; `[hidden]` (set/cleared by juneau-views.js)
@@ -863,6 +882,19 @@ table.dataTable thead .sorting_desc_disabled:after {
font-family: inherit;
}
+/* Scoped to the toolkit's own toolbar search input only - never a bare `::placeholder`, which would be a
+ stronger claim on a consumer's page than a framework should make. Two separate rules (DT1 / DT2 markup),
+ never a comma list, per this file's own comma-joined-selector caution. Italic only; no opacity drop, since
+ the input's accessible name comes from an explicit aria-label (stamped in buildToolbarRow), not from the
+ placeholder text, so there is no accessibility reason to fade it. */
+.juneau-view-toolbar-right .dataTables_filter input::placeholder {
+ font-style: italic;
+}
+
+.juneau-view-toolbar-right .dt-search input::placeholder {
+ font-style: italic;
+}
+
.juneau-view-ribbon-divider {
display: inline-block;
width: 0.5em; /* pure spacing only; no visible glyph. Stays in the DOM (unchanged JS branch). */
@@ -870,12 +902,15 @@ table.dataTable thead .sorting_desc_disabled:after {
/*
* Per-table staleness indicator (per-table, never a single page-level chip) - a small neutral text chip
- * juneau-views.js inserts at the front of the toolbar row's RIGHT cluster for any table that declares a
+ * juneau-views.js appends to the end of the toolbar row's RIGHT cluster (against the cluster itself, never
+ * against a specific sibling, since a view may poll with no ribbon at all) for any table that declares a
* `pollIntervalMs`. NEUTRAL - no palette color (per this file's no-color contract); the `data-state="error"`
* case ("the last refresh attempt failed" must look visibly distinct from a merely-aging timestamp) gets a
* heavier border/bold text instead of a color change, mirroring the
* ".juneau-view-ribbon-btn[aria-pressed=\"true\"]" neutral-emphasis convention above; console-ui's chrome.css
- * MAY layer a themed color onto this same attribute selector when present.
+ * MAY layer a themed color onto this same attribute selector when present. The min-width below reserves room
+ * for the longest rendered text (error-state, two-digit) so a shorter state cannot let the trailing refresh
+ * button jump sideways as the label ticks.
*/
.juneau-view-staleness {
display: inline-flex;
@@ -885,6 +920,7 @@ table.dataTable thead .sorting_desc_disabled:after {
border-radius: 0.75em;
font-size: 0.8125rem;
white-space: nowrap;
+ min-width: 38ch;
}
.juneau-view-staleness[data-state="error"] {
@@ -911,6 +947,13 @@ table.dataTable thead .sorting_desc_disabled:after {
border-radius: 0.2em;
}
+/* Same scoped-italic-placeholder treatment as the toolbar search input above, and the same paired
+ aria-label reasoning - here the label is already stamped (input.setAttribute("aria-label", label),
+ alongside input.placeholder) where this input is built. */
+.juneau-view-columnsearch-input::placeholder {
+ font-style: italic;
+}
+
/*
* Self-contained ".jc-*" tabs/sub-tabs page shell (Decision 1(A)). Folded into this file rather than a separate
* juneau-pages.css: small enough not to warrant its own served asset/pom touch (see the module's ViewsMixin
diff --git a/juneau-rest/juneau-rest-server-views/src/main/resources/org/apache/juneau/views/juneau-views.js b/juneau-rest/juneau-rest-server-views/src/main/resources/org/apache/juneau/views/juneau-views.js
index a32df53a5a..397d9d6dd3 100644
--- a/juneau-rest/juneau-rest-server-views/src/main/resources/org/apache/juneau/views/juneau-views.js
+++ b/juneau-rest/juneau-rest-server-views/src/main/resources/org/apache/juneau/views/juneau-views.js
@@ -1093,7 +1093,11 @@
const right = document.createElement("div");
right.className = "juneau-view-toolbar-right";
- if (filterEl) right.appendChild(filterEl);
+ if (filterEl) {
+ const filterInput = filterEl.querySelector("input");
+ if (filterInput) filterInput.setAttribute("aria-label", "Search table");
+ right.appendChild(filterEl);
+ }
if (bar) right.appendChild(bar);
row.appendChild(left);
@@ -4353,7 +4357,9 @@
if (!viewDef.pollIntervalMs || !toolbarRow) return;
const staleness = buildStalenessIndicator();
const rightCluster = toolbarRow.querySelector(".juneau-view-toolbar-right");
- if (rightCluster) rightCluster.insertBefore(staleness, rightCluster.firstChild);
+ // Appended against the CLUSTER, never against a specific sibling (e.g. a trailing refresh group) - a
+ // view may declare a poll interval with no ribbon at all, so there may be no sibling to anchor to.
+ if (rightCluster) rightCluster.appendChild(staleness);
initPolling(table, ctx.dataTable, viewDef, staleness, ctx);
}
diff --git a/juneau-rest/juneau-rest-server-views/src/test/java/org/apache/juneau/rest/server/views/TablePolling_Wiring_Test.java b/juneau-rest/juneau-rest-server-views/src/test/java/org/apache/juneau/rest/server/views/TablePolling_Wiring_Test.java
index 9efcdc85b4..2e706f860d 100644
--- a/juneau-rest/juneau-rest-server-views/src/test/java/org/apache/juneau/rest/server/views/TablePolling_Wiring_Test.java
+++ b/juneau-rest/juneau-rest-server-views/src/test/java/org/apache/juneau/rest/server/views/TablePolling_Wiring_Test.java
@@ -151,7 +151,7 @@ class TablePolling_Wiring_Test extends TestBase {
assertTrue(initBody.contains("buildStalenessIndicator()"), initBody);
assertTrue(initBody.contains("initPolling(table, ctx.dataTable, viewDef, staleness, ctx)"), initBody);
assertTrue(initBody.contains(".juneau-view-toolbar-right"), initBody);
- assertTrue(initBody.contains("insertBefore(staleness, rightCluster.firstChild)"), initBody);
+ assertTrue(initBody.contains("rightCluster.appendChild(staleness)"), initBody);
}
@Test void b08_initPolling_storesIntervalIds_andClearsLeftovers() throws Exception {