From 30ac8222550a0e4309b72c440cf49cd947318d52 Mon Sep 17 00:00:00 2001 From: Ophir Lojkine Date: Mon, 14 Sep 2026 07:37:42 +0000 Subject: [PATCH 1/3] fix(big_number) :: preserve color and spacing --- CHANGELOG.md | 2 ++ .../sqlpage/migrations/49_big_number.sql | 2 +- sqlpage/sqlpage.css | 4 +++ sqlpage/templates/big_number.handlebars | 6 ++-- .../end-to-end/fixtures/big-number/index.sql | 16 +++++++++ tests/end-to-end/fixtures/big-number/test.ts | 34 +++++++++++++++++++ 6 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 tests/end-to-end/fixtures/big-number/index.sql create mode 100644 tests/end-to-end/fixtures/big-number/test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index e149c7f4..62877cb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## unreleased +- Big number cards with a `color` once again display their main value in that color in light and dark themes, including values with a link. Their compact vertical padding has also been restored. + ## v0.46.2 - Numeric x values on Cartesian charts now explicitly use a continuous numeric axis, preventing fractional tick positions from being displayed as misleading rounded integers. diff --git a/examples/official-site/sqlpage/migrations/49_big_number.sql b/examples/official-site/sqlpage/migrations/49_big_number.sql index 17c4dccf..42e93e96 100644 --- a/examples/official-site/sqlpage/migrations/49_big_number.sql +++ b/examples/official-site/sqlpage/migrations/49_big_number.sql @@ -22,7 +22,7 @@ INSERT INTO parameter(component, name, description, type, top_level, optional) S ('progress_percent', 'The value of the progress (0-100).', 'INTEGER', FALSE, TRUE), ('progress_color', 'The color of the progress bar (e.g., "primary", "success", "danger").', 'TEXT', FALSE, TRUE), ('dropdown_item', 'A list of JSON objects containing links. e.g. {"label":"This week", "link":"?days=7"}', 'JSON', FALSE, TRUE), - ('color', 'The color of the card', 'COLOR', FALSE, TRUE) + ('color', 'The color of the card background and its main value.', 'COLOR', FALSE, TRUE) ) x; INSERT INTO example(component, description, properties) VALUES diff --git a/sqlpage/sqlpage.css b/sqlpage/sqlpage.css index 2976dd62..cc11373b 100644 --- a/sqlpage/sqlpage.css +++ b/sqlpage/sqlpage.css @@ -50,6 +50,10 @@ td > p { --tblr-datagrid-item-width: 6rem; } +.sqlpage-big-number-card { + --tblr-card-spacer-y: 1rem; +} + code { font-size: 100%; } diff --git a/sqlpage/templates/big_number.handlebars b/sqlpage/templates/big_number.handlebars index 31eb05ec..84b7eeb5 100644 --- a/sqlpage/templates/big_number.handlebars +++ b/sqlpage/templates/big_number.handlebars @@ -8,7 +8,7 @@ {{#unless ../columns}}style="min-width: 9rem;"{{/unless}} {{~#if id}} id="{{id}}"{{/if~}} > -
+
{{#if title}} @@ -47,10 +47,10 @@ {{/if}}
-
+
{{#if value_link}} diff --git a/tests/end-to-end/fixtures/big-number/index.sql b/tests/end-to-end/fixtures/big-number/index.sql new file mode 100644 index 00000000..5ad27559 --- /dev/null +++ b/tests/end-to-end/fixtures/big-number/index.sql @@ -0,0 +1,16 @@ +SELECT + 'big_number' AS component, + 2 AS columns; + +SELECT + 'plain-color' AS id, + 'Plain value' AS title, + '1,234' AS value, + 'red' AS color; + +SELECT + 'linked-color' AS id, + 'Linked value' AS title, + '5,678' AS value, + 'blue' AS color, + '#linked-color' AS value_link; diff --git a/tests/end-to-end/fixtures/big-number/test.ts b/tests/end-to-end/fixtures/big-number/test.ts new file mode 100644 index 00000000..d2a186df --- /dev/null +++ b/tests/end-to-end/fixtures/big-number/test.ts @@ -0,0 +1,34 @@ +import { expect, test } from "../../fixture"; + +for (const theme of ["light", "dark"]) { + test(`colored values match their cards in the ${theme} theme`, async ({ + page, + }) => { + await page.locator("html").evaluate((html, selectedTheme) => { + html.dataset.bsTheme = selectedTheme; + }, theme); + + for (const { id, linked } of [ + { id: "plain-color", linked: false }, + { id: "linked-color", linked: true }, + ]) { + const styles = await page.locator(`#${id}`).evaluate((item) => ({ + card: getComputedStyle(item.querySelector(".card") as HTMLElement) + .color, + verticalSpacing: getComputedStyle( + item.querySelector(".card") as HTMLElement, + ) + .getPropertyValue("--tblr-card-spacer-y") + .trim(), + value: getComputedStyle(item.querySelector(".h1") as HTMLElement).color, + link: item.querySelector(".h1 a") + ? getComputedStyle(item.querySelector(".h1 a") as HTMLElement).color + : null, + })); + + expect(styles.value).toBe(styles.card); + expect(styles.link).toBe(linked ? styles.card : null); + expect(styles.verticalSpacing).toBe("1rem"); + } + }); +} From 6d9298e91644201c6c21d7badc45130745af14f8 Mon Sep 17 00:00:00 2001 From: Ophir Lojkine Date: Mon, 14 Sep 2026 08:38:50 +0000 Subject: [PATCH 2/3] refactor(big_number) :: keep spacing local --- sqlpage/sqlpage.css | 4 ---- sqlpage/templates/big_number.handlebars | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/sqlpage/sqlpage.css b/sqlpage/sqlpage.css index cc11373b..2976dd62 100644 --- a/sqlpage/sqlpage.css +++ b/sqlpage/sqlpage.css @@ -50,10 +50,6 @@ td > p { --tblr-datagrid-item-width: 6rem; } -.sqlpage-big-number-card { - --tblr-card-spacer-y: 1rem; -} - code { font-size: 100%; } diff --git a/sqlpage/templates/big_number.handlebars b/sqlpage/templates/big_number.handlebars index 84b7eeb5..6f945f17 100644 --- a/sqlpage/templates/big_number.handlebars +++ b/sqlpage/templates/big_number.handlebars @@ -8,7 +8,7 @@ {{#unless ../columns}}style="min-width: 9rem;"{{/unless}} {{~#if id}} id="{{id}}"{{/if~}} > -
+
{{#if title}} From f4bd6e970b92a53b8b640bc5c6d990176734f2dd Mon Sep 17 00:00:00 2001 From: lovasoa Date: Tue, 15 Sep 2026 16:18:57 +0200 Subject: [PATCH 3/3] Test big-number colors with real shell themes and verify rendered padding --- sqlpage/templates/big_number.handlebars | 2 +- .../end-to-end/fixtures/big-number/index.sql | 7 +++ tests/end-to-end/fixtures/big-number/test.ts | 48 +++++++++++-------- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/sqlpage/templates/big_number.handlebars b/sqlpage/templates/big_number.handlebars index 6f945f17..385b2ccf 100644 --- a/sqlpage/templates/big_number.handlebars +++ b/sqlpage/templates/big_number.handlebars @@ -50,7 +50,7 @@
{{#if value_link}} diff --git a/tests/end-to-end/fixtures/big-number/index.sql b/tests/end-to-end/fixtures/big-number/index.sql index 5ad27559..6070f5b3 100644 --- a/tests/end-to-end/fixtures/big-number/index.sql +++ b/tests/end-to-end/fixtures/big-number/index.sql @@ -1,3 +1,5 @@ +SELECT 'shell' AS component, COALESCE($theme, 'light') AS theme; + SELECT 'big_number' AS component, 2 AS columns; @@ -14,3 +16,8 @@ SELECT '5,678' AS value, 'blue' AS color, '#linked-color' AS value_link; + +SELECT + 'default-color' AS id, + 'Default value' AS title, + '9,012' AS value; diff --git a/tests/end-to-end/fixtures/big-number/test.ts b/tests/end-to-end/fixtures/big-number/test.ts index d2a186df..a157eb9e 100644 --- a/tests/end-to-end/fixtures/big-number/test.ts +++ b/tests/end-to-end/fixtures/big-number/test.ts @@ -4,31 +4,41 @@ for (const theme of ["light", "dark"]) { test(`colored values match their cards in the ${theme} theme`, async ({ page, }) => { - await page.locator("html").evaluate((html, selectedTheme) => { - html.dataset.bsTheme = selectedTheme; - }, theme); + await page.goto(`/big-number/?theme=${theme}`); + await expect(page.locator("body")).toHaveAttribute("data-bs-theme", theme); + await expect(page.locator("body")).toHaveCSS("color-scheme", theme); + + const defaultColor = await page + .locator("#default-color .h1") + .evaluate((value) => getComputedStyle(value).color); + const rem = await page + .locator("html") + .evaluate((html) => Number.parseFloat(getComputedStyle(html).fontSize)); for (const { id, linked } of [ { id: "plain-color", linked: false }, { id: "linked-color", linked: true }, ]) { - const styles = await page.locator(`#${id}`).evaluate((item) => ({ - card: getComputedStyle(item.querySelector(".card") as HTMLElement) - .color, - verticalSpacing: getComputedStyle( - item.querySelector(".card") as HTMLElement, - ) - .getPropertyValue("--tblr-card-spacer-y") - .trim(), - value: getComputedStyle(item.querySelector(".h1") as HTMLElement).color, - link: item.querySelector(".h1 a") - ? getComputedStyle(item.querySelector(".h1 a") as HTMLElement).color - : null, - })); + const item = page.locator(`#${id}`); + const cardColor = await item + .locator(".card") + .evaluate((card) => getComputedStyle(card).color); - expect(styles.value).toBe(styles.card); - expect(styles.link).toBe(linked ? styles.card : null); - expect(styles.verticalSpacing).toBe("1rem"); + // Matching two default-colored elements must not count as a color fix. + expect(cardColor).not.toBe(defaultColor); + await expect(item.locator(".h1")).toHaveCSS("color", cardColor); + await expect(item.locator(".h1 a")).toHaveCount(linked ? 1 : 0); + if (linked) { + await expect(item.locator(".h1 a")).toHaveCSS("color", cardColor); + } + await expect(item.locator(".card-body")).toHaveCSS( + "padding-top", + `${rem}px`, + ); + await expect(item.locator(".card-body")).toHaveCSS( + "padding-bottom", + `${rem}px`, + ); } }); }