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/09/18 14:33:09 UTC
(juneau) branch master updated: Give Juneau ownership of the gray .jc-main well, white content cards, and transparent table-chrome so apps stop forking those paints.
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 961d1d9c3d Give Juneau ownership of the gray .jc-main well, white content cards, and transparent table-chrome so apps stop forking those paints.
961d1d9c3d is described below
commit 961d1d9c3d72e2eab904e7407e39a213ee281b7f
Author: James Bognar <ja...@apache.org>
AuthorDate: Fri Sep 18 10:33:02 2026 -0400
Give Juneau ownership of the gray .jc-main well, white content cards, and transparent table-chrome so apps stop forking those paints.
---
.../apache/juneau/rest/server/console/Theme.java | 16 +++--
.../resources/org/apache/juneau/console/chrome.css | 44 +++++++------
.../server/console/ChromeCss_FullBleed_Test.java | 10 +--
.../server/console/ChromeCss_MainInner_Test.java | 73 ++++++++++++++++++++++
.../server/console/ConsoleChromeMixin_Test.java | 18 ++----
.../rest/server/console/Theme_Gray_Test.java | 7 ++-
.../rest/server/console/Theme_LightBrown_Test.java | 7 ++-
.../rest/server/console/Theme_LightRed_Test.java | 7 ++-
.../juneau/rest/server/console/Theme_Red_Test.java | 4 +-
.../org/apache/juneau/views/juneau-views.css | 20 +++---
.../rest/server/views/ViewsMixin_Serving_Test.java | 29 +++++----
11 files changed, 164 insertions(+), 71 deletions(-)
diff --git a/juneau-rest/juneau-rest-server-console-ui/src/main/java/org/apache/juneau/rest/server/console/Theme.java b/juneau-rest/juneau-rest-server-console-ui/src/main/java/org/apache/juneau/rest/server/console/Theme.java
index a6f6314818..f9be75a3b3 100644
--- a/juneau-rest/juneau-rest-server-console-ui/src/main/java/org/apache/juneau/rest/server/console/Theme.java
+++ b/juneau-rest/juneau-rest-server-console-ui/src/main/java/org/apache/juneau/rest/server/console/Theme.java
@@ -106,7 +106,7 @@ public final class Theme {
.token("--jc-text-muted", "#706e6b")
.token("--jc-border", "#dddbda")
.token("--jc-border-2", "#ced4da")
- .token("--jc-card-bg", "#f5f6f9")
+ .token("--jc-card-bg", "#ffffff")
.token("--jc-chrome-bg", "#f3f2f2")
.token("--jc-white", "#ffffff")
.token("--jc-btn-primary", "#1a5297")
@@ -159,6 +159,7 @@ public final class Theme {
// this token; it must be overridden on its own. A permanent widening of the theming surface.
.token("--jc-accent-selected", "#1589EE")
.token("--jc-table-stripe-bg", "#fafaf9")
+ .token("--jc-main-bg", "#f5f6f9") // inner-main well; not a retarget of old card tints
.build();
/**
@@ -169,7 +170,7 @@ public final class Theme {
* every one of {@link #OPEN}'s semantic status/tag tokens (info blue, success green, danger red, warning amber,
* neutral gray) verbatim — a brown "danger" pill would stop reading as danger, so the status palette is
* deliberately untouched. Authored as {@link #deriveFrom(String, Theme) deriveFrom}({@link #OPEN}), overriding
- * only the 16 browned tokens below; the other 36 — including all five tag triads and every structural
+ * only the 15 browned tokens below; the other 38 — including all five tag triads and every structural
* token — are inherited from {@link #OPEN} unchanged, so this theme's token <i>key</i> set is provably
* identical to {@link #OPEN}'s.
*
@@ -189,7 +190,6 @@ public final class Theme {
.token("--jc-text-muted", "#7a6a4f")
.token("--jc-border", "#d8cbb0")
.token("--jc-border-2", "#c9b896")
- .token("--jc-card-bg", "#fbf8f1")
.token("--jc-chrome-bg", "#efe6d4")
.token("--jc-btn-primary", "#8a6d3b")
.token("--jc-btn-primary-hover", "#74592f")
@@ -206,7 +206,7 @@ public final class Theme {
* every one of {@link #OPEN}'s semantic status/tag tokens (info blue, success green, danger red, warning amber,
* neutral gray) verbatim — a red "danger" pill that matched the brand would stop reading as danger, so
* the status palette is deliberately untouched. Authored as {@link #deriveFrom(String, Theme) deriveFrom}({@link #OPEN}),
- * overriding only the 16 recolored tokens below; the other 36 — including all five tag triads and every
+ * overriding only the 15 recolored tokens below; the other 38 — including all five tag triads and every
* structural token — are inherited from {@link #OPEN} unchanged, so this theme's token <i>key</i> set is
* provably identical to {@link #OPEN}'s.
*
@@ -230,7 +230,6 @@ public final class Theme {
.token("--jc-text-muted", "#6e585c")
.token("--jc-border", "#e4d4d7")
.token("--jc-border-2", "#d4c2c6")
- .token("--jc-card-bg", "#fbf8f9")
.token("--jc-chrome-bg", "#f3ecee")
.token("--jc-btn-primary", "#6B1D2A")
.token("--jc-btn-primary-hover", "#541620")
@@ -291,9 +290,9 @@ public final class Theme {
* amber, neutral gray) <b>and</b> {@link #OPEN}'s blue interactive affordances (accent, link, primary button,
* focus ring, avatar gradient) verbatim — a pure-grayscale accent would make links/buttons stop reading
* as clickable, so the restrained blue affordance set is deliberately left untouched (this is the
- * "8 grayed / 44 kept" derivation; see the design item for the vetoed all-monochrome alternative). Authored
- * as {@link #deriveFrom(String, Theme) deriveFrom}({@link #OPEN}), overriding only the 8 grayed tokens below;
- * the other 44 — including all five tag triads, every structural token, and the blue affordance set
+ * "7 grayed / 46 kept" derivation; see the design item for the vetoed all-monochrome alternative). Authored
+ * as {@link #deriveFrom(String, Theme) deriveFrom}({@link #OPEN}), overriding only the 7 grayed tokens below;
+ * the other 46 — including all five tag triads, every structural token, and the blue affordance set
* — are inherited from {@link #OPEN} unchanged, so this theme's token <i>key</i> set is provably
* identical to {@link #OPEN}'s.
*
@@ -309,7 +308,6 @@ public final class Theme {
.token("--jc-text-muted", "#737373")
.token("--jc-border", "#e0e0e0")
.token("--jc-border-2", "#d0d0d0")
- .token("--jc-card-bg", "#f7f7f7")
.token("--jc-chrome-bg", "#f4f4f4")
.build();
diff --git a/juneau-rest/juneau-rest-server-console-ui/src/main/resources/org/apache/juneau/console/chrome.css b/juneau-rest/juneau-rest-server-console-ui/src/main/resources/org/apache/juneau/console/chrome.css
index 320e01829d..c71ab12778 100644
--- a/juneau-rest/juneau-rest-server-console-ui/src/main/resources/org/apache/juneau/console/chrome.css
+++ b/juneau-rest/juneau-rest-server-console-ui/src/main/resources/org/apache/juneau/console/chrome.css
@@ -447,13 +447,15 @@ a:hover { text-decoration: underline; }
flex: 1 1 auto;
padding: 20px 24px 40px;
min-width: 0;
+ background-color: var(--jc-main-bg);
+ margin: var(--jc-space-3);
+ border-radius: var(--jc-radius);
}
.jc-page-header {
display: flex;
align-items: baseline;
justify-content: space-between;
- max-width: 1180px;
margin: 0 auto 14px;
flex-wrap: wrap;
gap: 10px;
@@ -486,7 +488,6 @@ a:hover { text-decoration: underline; }
========================================================================== */
.jc-card {
- max-width: 1180px;
margin: 0 auto;
background-color: var(--jc-card-bg);
border: none;
@@ -512,29 +513,36 @@ a:hover { text-decoration: underline; }
}
/* ==========================================================================
- TODO-445n full horizontal real estate (Goal 1)
+ Table-chrome detector (data-juneau-layout="wide")
==========================================================================
- ViewTable stamps `data-juneau-layout="wide"` on the ONE stamp node it emits (its wrapper <div>). This is a
- first-class public data-juneau-* convention (allowed value: "wide"; never stamped on .jc-card / .jc-main — the
- toolkit emits neither class). The wide wrapper widens itself, and the enclosing card/main expand off it via
- :has(), so a wide table page uses the full content-area width instead of the default centered 1180px card.
-
- Position-dependent wide-stamp matrix:
- - the wrapper itself -> always widened
- - .jc-card -> widened ONLY when the wide wrapper is a DIRECT child (typical after the RM
- .rm-table-scroll unwrap)
- - .jc-main -> widened when ANY descendant wrapper is wide
- `.jc-main` keeps its padding; `max-width:none` means edge-of-content-area, not edge-of-viewport.
- `min-width:0` (declared on .jc-main's single rule up in "Page scaffolding") lets the main region shrink below
- the table's intrinsic width so the table-region scroll box (juneau-views.css), not the page, absorbs overflow
- (INV-3). */
+ ViewTable stamps `data-juneau-layout="wide"` on the ONE stamp node it emits (its wrapper <div>).
+ This is a first-class public data-juneau-* convention (allowed value: "wide"; never stamped on
+ .jc-card / .jc-main — the toolkit emits neither class). After cards fill the main well, the
+ stamp is the table-chrome detector, not a width punch-through: the outer .jc-card that contains
+ the stamp goes transparent and unpadded so Table Toolbar + Summary View sit on the gray well.
+ Nested .jc-card descendants stay content cards (`:not(.jc-card .jc-card)`).
+
+ Position-dependent matrix:
+ - the wrapper itself -> still widened (self-match)
+ - outer .jc-card containing the stamp (HTML-slot: stamp may sit inside a slot <div>)
+ -> table-chrome (transparent, padding 0); descendant :has
+ - nested .jc-card -> never table-chrome
+ - .jc-main -> max-width:none when ANY descendant wrapper is wide (harmless;
+ .jc-main has no max-width of its own)
+ `.jc-main` keeps its padding; `min-width:0` lets the main region shrink below the table's
+ intrinsic width so the table-region scroll box (juneau-views.css), not the page, absorbs overflow.
+*/
[data-juneau-layout="wide"] {
max-width: none;
width: 100%;
}
-.jc-card:has(> [data-juneau-layout="wide"]),
+.jc-card:has([data-juneau-layout="wide"]):not(.jc-card .jc-card) {
+ background-color: transparent;
+ padding: 0;
+}
+
.jc-main:has([data-juneau-layout="wide"]) {
max-width: none;
}
diff --git a/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/ChromeCss_FullBleed_Test.java b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/ChromeCss_FullBleed_Test.java
index dd8c0bdd0c..e636d17ce4 100644
--- a/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/ChromeCss_FullBleed_Test.java
+++ b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/ChromeCss_FullBleed_Test.java
@@ -74,11 +74,13 @@ class ChromeCss_FullBleed_Test extends TestBase {
return css.substring(braceIdx + 1, endIdx < 0 ? css.length() : endIdx).contains(needle);
}
- /** The ancestor card widens only when the wide wrapper is a DIRECT child (position-dependent matrix). */
- @Test void a02_cardExpandsViaHasDirectChild() throws Exception {
+ /** Outer table-chrome is descendant :has plus :not nested .jc-card (HTML-slot stamp is not a direct child). */
+ @Test void a02_tableChrome_isDescendantHas_notDirectChildOnly() throws Exception {
var c = flat();
- assertTrue(c.contains(".jc-card:has(> [data-juneau-layout=\"wide\"])"),
- "the card must expand via :has(> [data-juneau-layout=\"wide\"]) - direct-child only (wide-stamp matrix)");
+ assertTrue(c.contains(".jc-card:has([data-juneau-layout=\"wide\"]):not(.jc-card .jc-card)"),
+ "outer table-chrome must be descendant :has + :not nested .jc-card");
+ assertFalse(c.contains(".jc-card:has(> [data-juneau-layout=\"wide\"])"),
+ "direct-child-only :has(>) misses HTML-slot and is not the detector");
}
/** The main region widens when any descendant wrapper is wide. */
diff --git a/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/ChromeCss_MainInner_Test.java b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/ChromeCss_MainInner_Test.java
new file mode 100644
index 0000000000..21f33ac76e
--- /dev/null
+++ b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/ChromeCss_MainInner_Test.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.juneau.rest.server.console;
+
+import static java.nio.charset.StandardCharsets.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.*;
+
+import org.apache.juneau.*;
+import org.junit.jupiter.api.*;
+
+/**
+ * Pins the inner-main well, card fill-width, and outer table-chrome contracts in {@code chrome.css}.
+ */
+class ChromeCss_MainInner_Test extends TestBase {
+
+ private static String readChromeCss() throws IOException {
+ try (var in = ChromeCss_MainInner_Test.class.getResourceAsStream("/org/apache/juneau/console/chrome.css")) {
+ assertNotNull(in, "missing classpath resource: /org/apache/juneau/console/chrome.css");
+ return new String(in.readAllBytes(), UTF_8);
+ }
+ }
+
+ private static String flat() throws IOException {
+ return readChromeCss().replaceAll("\\s+", " ");
+ }
+
+ @Test void a01_jcMain_paintsMainBg_gutter_radius_noBorder() throws Exception {
+ var c = flat();
+ assertTrue(c.contains(".jc-main {"), ".jc-main rule missing");
+ var start = c.indexOf(".jc-main {");
+ var end = c.indexOf('}', start);
+ var body = c.substring(start, end);
+ assertTrue(body.contains("background-color: var(--jc-main-bg)"), body);
+ assertTrue(body.contains("margin: var(--jc-space-3)"), body);
+ assertTrue(body.contains("border-radius: var(--jc-radius)"), body);
+ assertFalse(body.contains("max-width:"), "Q4: no max-width on .jc-main: " + body);
+ assertFalse(body.contains("border:"), "Q4: no extra border on .jc-main: " + body);
+ assertTrue(body.contains("padding: 20px 24px 40px"), "keep today's inner padding: " + body);
+ }
+
+ @Test void a02_cardAndPageHeader_haveNo1180MaxWidth() throws Exception {
+ var css = readChromeCss();
+ assertFalse(css.contains("max-width: 1180px"), "Q5: drop max-width 1180px on .jc-card / .jc-page-header");
+ }
+
+ @Test void a03_tableChrome_transparentUnpadded_outerOnly() throws Exception {
+ var c = flat();
+ var sel = ".jc-card:has([data-juneau-layout=\"wide\"]):not(.jc-card .jc-card)";
+ assertTrue(c.contains(sel), "missing table-chrome selector");
+ var start = c.indexOf(sel);
+ var brace = c.indexOf('{', start);
+ var end = c.indexOf('}', brace);
+ var body = c.substring(brace, end);
+ assertTrue(body.contains("background-color: transparent"), body);
+ assertTrue(body.contains("padding: 0"), body);
+ }
+}
diff --git a/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/ConsoleChromeMixin_Test.java b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/ConsoleChromeMixin_Test.java
index b03d06c3f2..08e59a454d 100644
--- a/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/ConsoleChromeMixin_Test.java
+++ b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/ConsoleChromeMixin_Test.java
@@ -561,23 +561,17 @@ class ConsoleChromeMixin_Test extends TestBase {
}
@Test void j03_themeOpenTokenCount_pinned_unaffectedByAssetsFeature() {
- // A0 must not add a --jc-logo or --jc-page-bg-image token - the logo/page-bg mechanism is deliberately
- // NOT part of the Theme token model (finding 4 of the design doc). If this count ever changes, it must be
- // a DIFFERENT, deliberate change to Theme.OPEN - not a side effect of the asset feature.
- //
- // 52 = the original 32, plus the three-token red tag triad, plus the fourteen additive
- // token gaps (--jc-header-height, --jc-nav-indicator-width, --jc-page-nav-hairline,
- // --jc-page-nav-section-font-size, --jc-page-nav-child-font-size, --jc-card-shadow,
- // --jc-danger-wash, --jc-success-wash, and the six-step --jc-space-1..6 scale), plus the --jc-focus
- // focus-ring colour, plus the --jc-accent-selected ribbon-format selected-state face (WCAG 1.4.11
- // non-text contrast remedy), plus --jc-table-stripe-bg (#fafaf9; not aliased to --jc-card-bg).
- // Bumping this number is only ever correct alongside a reviewed edit to Theme.OPEN itself.
- assertEquals(52, Theme.OPEN.getTokens().size());
+ // 53 = previous 52 plus --jc-main-bg (inner-main well). --jc-card-bg is now
+ // content-card white; do not retarget old card tints onto --jc-main-bg.
+ assertEquals(53, Theme.OPEN.getTokens().size());
+ assertEquals("#f5f6f9", Theme.OPEN.getTokens().get("--jc-main-bg"));
+ assertEquals("#ffffff", Theme.OPEN.getTokens().get("--jc-card-bg"));
assertEquals("2px", Theme.OPEN.getTokens().get("--jc-page-nav-hairline"));
assertEquals("13px", Theme.OPEN.getTokens().get("--jc-page-nav-section-font-size"));
assertEquals("12px", Theme.OPEN.getTokens().get("--jc-page-nav-child-font-size"));
assertFalse(Theme.OPEN.getTokens().containsKey("--jc-logo"));
assertFalse(Theme.OPEN.getTokens().containsKey("--jc-page-bg-image"));
+ assertFalse(Theme.OPEN.getTokens().containsKey("--jc-card-surface"));
}
@Test void j04_accentSelectedFace_meetsWcag1411NonTextContrast_andBothSelectorsConsumeToken() throws Exception {
diff --git a/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_Gray_Test.java b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_Gray_Test.java
index a1548a0440..55eed80f87 100644
--- a/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_Gray_Test.java
+++ b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_Gray_Test.java
@@ -36,8 +36,8 @@ class Theme_Gray_Test extends TestBase {
assertEquals(Theme.OPEN.getTokens().keySet(), Theme.GRAY.getTokens().keySet());
}
- @Test void a02_tokenCount_is52_mirroringOpensPin() {
- assertEquals(52, Theme.GRAY.getTokens().size());
+ @Test void a02_tokenCount_is53_mirroringOpensPin() {
+ assertEquals(53, Theme.GRAY.getTokens().size());
}
@Test void a03_name_isGray() {
@@ -63,6 +63,9 @@ class Theme_Gray_Test extends TestBase {
assertEquals("#1589EE", tokens.get("--jc-accent"));
assertEquals(Theme.OPEN.getTokens().get("--jc-link"), tokens.get("--jc-link"));
assertEquals(Theme.OPEN.getTokens().get("--jc-btn-primary"), tokens.get("--jc-btn-primary"));
+ assertEquals(Theme.OPEN.getTokens().get("--jc-card-bg"), tokens.get("--jc-card-bg"));
+ assertEquals("#ffffff", tokens.get("--jc-card-bg"));
+ assertEquals(Theme.OPEN.getTokens().get("--jc-main-bg"), tokens.get("--jc-main-bg"));
}
@Test void b03_noVarReferencesLeak_everyValueIsAResolvedLiteral() {
diff --git a/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_LightBrown_Test.java b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_LightBrown_Test.java
index ae6b3e3f7a..8382fe5531 100644
--- a/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_LightBrown_Test.java
+++ b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_LightBrown_Test.java
@@ -36,8 +36,8 @@ class Theme_LightBrown_Test extends TestBase {
assertEquals(Theme.OPEN.getTokens().keySet(), Theme.LIGHT_BROWN.getTokens().keySet());
}
- @Test void a02_tokenCount_is52_mirroringOpensPin() {
- assertEquals(52, Theme.LIGHT_BROWN.getTokens().size());
+ @Test void a02_tokenCount_is53_mirroringOpensPin() {
+ assertEquals(53, Theme.LIGHT_BROWN.getTokens().size());
}
@Test void a03_name_isLightBrown() {
@@ -59,6 +59,9 @@ class Theme_LightBrown_Test extends TestBase {
assertEquals(Theme.OPEN.getTokens().get("--jc-success"), tokens.get("--jc-success"));
assertEquals(Theme.OPEN.getTokens().get("--jc-tag-green-bg"), tokens.get("--jc-tag-green-bg"));
assertEquals(Theme.OPEN.getTokens().get("--jc-tag-red-text"), tokens.get("--jc-tag-red-text"));
+ assertEquals(Theme.OPEN.getTokens().get("--jc-card-bg"), tokens.get("--jc-card-bg"));
+ assertEquals("#ffffff", tokens.get("--jc-card-bg"));
+ assertEquals(Theme.OPEN.getTokens().get("--jc-main-bg"), tokens.get("--jc-main-bg"));
}
@Test void b03_noVarReferencesLeak_everyValueIsAResolvedLiteral() {
diff --git a/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_LightRed_Test.java b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_LightRed_Test.java
index 258a3fdc59..0a0d3b5f7f 100644
--- a/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_LightRed_Test.java
+++ b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_LightRed_Test.java
@@ -36,8 +36,8 @@ class Theme_LightRed_Test extends TestBase {
assertEquals(Theme.OPEN.getTokens().keySet(), Theme.LIGHT_RED.getTokens().keySet());
}
- @Test void a02_tokenCount_is52_mirroringOpensPin() {
- assertEquals(52, Theme.LIGHT_RED.getTokens().size());
+ @Test void a02_tokenCount_is53_mirroringOpensPin() {
+ assertEquals(53, Theme.LIGHT_RED.getTokens().size());
}
@Test void a03_name_isLightRed() {
@@ -51,6 +51,9 @@ class Theme_LightRed_Test extends TestBase {
assertEquals("#6B1D2A", tokens.get("--jc-btn-primary"));
assertEquals("#f3ecee", tokens.get("--jc-chrome-bg"));
assertTrue(tokens.get("--jc-page-bg").contains("#e8cfd3"), () -> "expected the light-red gradient, got: " + tokens.get("--jc-page-bg"));
+ assertEquals(Theme.OPEN.getTokens().get("--jc-card-bg"), tokens.get("--jc-card-bg"));
+ assertEquals("#ffffff", tokens.get("--jc-card-bg"));
+ assertEquals(Theme.OPEN.getTokens().get("--jc-main-bg"), tokens.get("--jc-main-bg"));
}
@Test void b02_keptFromOpen_statusAndTagValues_areUnchanged() {
diff --git a/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_Red_Test.java b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_Red_Test.java
index bfbd3f7fe6..47422a8842 100644
--- a/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_Red_Test.java
+++ b/juneau-rest/juneau-rest-server-console-ui/src/test/java/org/apache/juneau/rest/server/console/Theme_Red_Test.java
@@ -36,8 +36,8 @@ class Theme_Red_Test extends TestBase {
assertEquals(Theme.OPEN.getTokens().keySet(), Theme.RED.getTokens().keySet());
}
- @Test void a02_tokenCount_is52_mirroringOpensPin() {
- assertEquals(52, Theme.RED.getTokens().size());
+ @Test void a02_tokenCount_is53_mirroringOpensPin() {
+ assertEquals(53, Theme.RED.getTokens().size());
}
@Test void a03_name_isRed() {
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 2f8ce3b950..f037a31c1e 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
@@ -1571,19 +1571,17 @@ div.dataTables_wrapper div.dataTables_filter input:focus-visible {
* The DataTables-native child row created by `row.child(panel).show()` (juneau-views.js) - class "child", per
* DataTables' own row.child() API, not one of this file's own "juneau-view-detail-*" names: Juneau never gets a
* handle on this <tr>/<td> to stamp its own class onto it, so it has to be reached by DataTables' own default
- * shape instead. Explicit opaque white (WORK-J0518 DF-12.1): without a background of its own the row/cell is
- * transparent, so ANY ancestor row styling - a zebra stripe, an "open" indicator, a hover wash on the row that
- * owns the expander - paints straight through it, including while that same row's hover state is still live.
- * The same "opaque floating/panel surface" exception this file already grants `.juneau-view-dialog` /
- * `.jc-cell-popover` / `.juneau-ts-popup`, extended to the one row DataTables itself creates rather than one
- * this file's own emit owns.
+ * shape instead. Opaque content-card fill (`--jc-card-bg`) plus `padding: 0` so ancestor row colouring (a zebra
+ * stripe, an "open" indicator, a hover wash) cannot show through, and the gray main well cannot halo the
+ * expanded panel.
*/
table[data-juneau-view] > tbody > tr.child,
table[data-juneau-view] > tbody > tr.child > td,
table.dataTable > tbody > tr.child,
table.dataTable > tbody > tr.child > td {
- background: #fff;
+ background-color: var(--jc-card-bg);
border: none;
+ padding: 0;
}
/* The expanded detail body itself - DataTables' native child row (juneau-views.js `row.child(...).show()`).
@@ -1591,7 +1589,13 @@ table.dataTable > tbody > tr.child > td {
.juneau-view-detail-panel {
margin: 0;
padding: var(--jc-space-2) var(--jc-space-3);
- background: #fff;
+ background-color: var(--jc-card-bg);
+}
+
+.juneau-view-detail-panel .jc-card,
+table[data-juneau-view] > tbody > tr.child .jc-card,
+table.dataTable > tbody > tr.child .jc-card {
+ margin: 0;
}
.juneau-view-detail-section {
diff --git a/juneau-rest/juneau-rest-server-views/src/test/java/org/apache/juneau/rest/server/views/ViewsMixin_Serving_Test.java b/juneau-rest/juneau-rest-server-views/src/test/java/org/apache/juneau/rest/server/views/ViewsMixin_Serving_Test.java
index 81e7afea1e..ab79634850 100644
--- a/juneau-rest/juneau-rest-server-views/src/test/java/org/apache/juneau/rest/server/views/ViewsMixin_Serving_Test.java
+++ b/juneau-rest/juneau-rest-server-views/src/test/java/org/apache/juneau/rest/server/views/ViewsMixin_Serving_Test.java
@@ -1189,13 +1189,10 @@ class ViewsMixin_Serving_Test extends TestBase {
}
/**
- * DF-12.1: the DataTables-native child row (row.child(...).show()) and this module's own detail panel are
- * explicit opaque white, so no ancestor row colouring (a zebra stripe, an "open" indicator, a parent-row
- * hover wash) can show through the expanded surface - the same "opaque floating/panel surface" exception
- * this file already grants the dialog/popover/timestamp-popup families, extended to the row DataTables
- * itself creates.
+ * The expanded-row Detail View is a flush content card: {@code --jc-card-bg} fill, inner padding,
+ * {@code margin: 0}, and child-row cells with {@code padding: 0} so the gray well cannot halo the panel.
*/
- @Test void p02_viewsCss_detailExpanderSurfaceIsOpaqueWhite() throws Exception {
+ @Test void p02_viewsCss_detailExpanderSurfaceIsOpaqueContentCard() throws Exception {
var body = cWithMixin.get(ViewsMixin.VIEWS_CSS_PATH).run().assertStatus(200).getContent().asString();
assertTrue(body.contains("table[data-juneau-view] > tbody > tr.child,\n"
+ "table[data-juneau-view] > tbody > tr.child > td,\n"
@@ -1203,16 +1200,24 @@ class ViewsMixin_Serving_Test extends TestBase {
+ "table.dataTable > tbody > tr.child > td {"), body);
var start = body.indexOf("table[data-juneau-view] > tbody > tr.child,");
var end = body.indexOf("}", start);
- assertTrue(body.substring(start, end).contains("background: #fff"), body);
- assertTrue(body.substring(start, end).contains("border: none"),
- () -> "expander child cells must not carry the summary-view grid: " + body.substring(start, end));
+ var child = body.substring(start, end);
+ assertTrue(child.contains("background-color: var(--jc-card-bg)"), child);
+ assertTrue(child.contains("padding: 0"), child);
+ assertTrue(child.contains("border: none"), child);
- // ".juneau-view-detail-panel {" appears TWICE (the container-query host near the top of the file, and
- // the expanded-body rule this test targets) - anchor on the body rule's own first declaration.
assertTrue(body.contains(".juneau-view-detail-panel {\n\tmargin: 0;"), body);
var panelStart = body.indexOf(".juneau-view-detail-panel {\n\tmargin: 0;");
var panelEnd = body.indexOf("}", panelStart);
- assertTrue(body.substring(panelStart, panelEnd).contains("background: #fff"), body);
+ var panel = body.substring(panelStart, panelEnd);
+ assertTrue(panel.contains("background-color: var(--jc-card-bg)"), panel);
+ assertFalse(panel.contains("background: #fff"), panel);
+
+ assertTrue(body.contains(".juneau-view-detail-panel .jc-card"),
+ "nested .jc-card inside the detail panel must be pinned");
+ var nestedStart = body.indexOf(".juneau-view-detail-panel .jc-card");
+ var nestedEnd = body.indexOf("}", nestedStart);
+ assertTrue(body.substring(nestedStart, nestedEnd).contains("margin: 0"),
+ body.substring(nestedStart, nestedEnd));
}
//------------------------------------------------------------------------------------------------------------------