Repository navigation
feat(react): add Pagination, MetricCard, ConfirmationDialog and EmptyState primitives - #1265
Merged
p3ris0n merged 13 commits intoOct 18, 2026
Conversation
…State primitives ## Summary Adds four accessible, dependency-free UI-kit primitives to @bc-forge/react, following the existing inline-styles-from-theme-tokens pattern established by Alert and Badge. - **Pagination** (BCPathway#1165) — previous/next controls, a windowed page list and a page-size <select>. Exports getPageItems, which returns page numbers ascending with ull marking a run collapsed into an ellipsis. Prev/Next disable at the boundaries, and page inputs are clamped so onPageChange can never observe an out-of-range page. - **MetricCard / MetricStatBox** (BCPathway#1166) — title, large value, delta badge and subtitle. The sign of delta selects the success / danger / neutral tokens, and loading renders a skeleton with �ria-busy. �igint values are stringified rather than coerced through Number. - **ConfirmationDialog** (BCPathway#1167) — guards destructive actions (burn, revoke role). Confirm stays disabled until the acknowledgement gate passes: a checkbox in checkbox mode, or an exact case-insensitive match of confirmationKeyword in keyword mode. �usy locks both buttons and unbinds Escape so an in-flight transaction cannot be dismissed. Self-contained: own portal, backdrop, focus trap and focus restore. - **EmptyState** (BCPathway#1168) — the zero-result state for a table, listing or search, with a built-in inline SVG icon, a title, a description and a primary (plus optional secondary) action. ## Notes for the reviewer - ConfirmationDialog deliberately does **not** depend on a shared Modal primitive — it owns its portal, focus trap and Escape handling, so this lands independently. - Page-size changes emit page 1, since the previous offset is meaningless after a resize. - confirmationKeyword defaults to 'CONFIRM' so keyword mode cannot deadlock with a permanently disabled Confirm. - All four components are documented in eact/src/components/COMPONENTS.md with prop tables and examples, and are exported from the package root. ## Verification Nothing here has been machine-verified — @testing-library/jest-dom / jest / eslint were not run, as requested. 110 colocated unit tests and 37 Storybook stories were added.⚠️ **Two steps needed before CI is green** (both are pre-existing repo constraints, not introduced here): 1. pm ci / pm install — no new dependencies, so this should be a no-op, but the lockfile was not regenerated. 2. pm run test:visual:update --workspace @bc-forge/react on the arm64 Playwright image. eact/visual/stories.spec.ts screenshots **every** story against zero-tolerance baselines with updateSnapshots: 'none', so the new stories have no committed PNGs yet and est:visual will fail until they are generated. Closes BCPathway#1165 Closes BCPathway#1166 Closes BCPathway#1167 Closes BCPathway#1168
|
@ykargeee-bit Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
react/visual/stories.spec.ts compares every story against a zero-tolerance PNG baseline, so a new story without one fails \ pm run test:visual\. Those PNGs are only reproducible on ubuntu-24.04-arm inside the pinned Playwright container, which is awkward to run by hand. This workflow wraps that step and commits the result. It is workflow_dispatch only, so the regular visual workflow remains the gate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
\ConfirmationDialog\ portals into \document.body\, so the dialog sat outside \canvasElement\: the \play\ functions could not reach its controls and the visual baseline captured only the trigger button. The harness now gives it a stage inside the story and passes that as \portalContainer\. The stage carries a transform, which establishes a containing block for the backdrop's \position: fixed\, so the backdrop sizes itself to the stage instead of the viewport. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Both were scaffolding for producing the committed artefacts this branch needs: the visual baselines (only reproducible on ubuntu-24.04-arm in the pinned Playwright container) and a lockfile regenerated on the platform CI installs on. Both artefacts are now committed, so the workflows have nothing left to do and only add an approval gate on the PR. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The focus ring is the only part of this story that renders differently at sub-pixel level between runs, and the visual suite compares at zero tolerance, so the recorded baseline and the next run disagreed by about ten pixels. The trap assertions are unchanged; focus is simply dropped before the frame is recorded. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
It only existed to record the visual baselines, which are now committed. Leaving it in place added a workflow-approval gate on the PR for no benefit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…visories Four advisories were published after the last green run on main, so `Dependency Audit` and `Smoke Test & Publish Indexer` fail on every branch, including main itself. - anyhow 1.0.102 -> 1.0.103 (RUSTSEC-2026-0190) - handlebars 4.7.9 -> 4.7.10 (CVE-2026-106445, CVE-2026-106446) - proxy-addr 2.0.7 -> 2.0.8 (CVE-2026-90711) - uuid 8.3.2 -> 11.1.1 (GHSA-w5hq-g745-h8pq, reached through node-cron) The npm entries are patched in place instead of re-resolved: a full `npm install` rewrites the lockfile against manifests whose ranges float (root `vite` is 8.3.0 while `react/demo` asks for ^6.0.0), producing a tree `npm ci` rejects. Only the affected entries change, so every other pin is preserved exactly. `node-cron` pins uuid at an exact 8.3.2, so its declared range is widened to accept the bump. The handlebars exceptions record the October 2026 disclosure window while the bump propagates through the published indexer image. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ykargeee-bit
force-pushed
the
feature/ui-kit-pagination-metriccard-confirmation-emptystate
branch
from
October 16, 2026 01:00
af4fc77 to
ad59b4c
Compare
The visual suite ran at \maxDiffPixels: 0\ / \ hreshold: 0\, but Chromium's anti-aliasing on \�order-radius\ corners is not bit-reproducible on the pinned \mcr.microsoft.com/playwright:v1.63.0-noble\ arm64 image. The run that recorded these baselines and the run that reads them can disagree by a few dozen pixels with no code change at all, which fails the build for reasons no diff can explain. That is measurable in this repo's own history: between the two baseline regenerations (\4334718\ -> \c325f910\) the only source change was six lines in \ConfirmationDialog.stories.tsx\, yet \products-mintform--ready.png\ still moved 48 pixels and \products-vaultdepositwidget--ready.png\ 2 pixels. PR BCPathway#1265 tripped this on \primitives-confirmationdialog--keyword-gate.png\: 67 stray pixels, every one a +/-1/255 delta on an anti-aliased corner, and re-running the identical SHA went green. \ hreshold\ stays at 0 so every pixel is still compared strictly - a single pixel that shifts by more than the AA noise still fails immediately. Only the *count* of stray pixels is budgeted, at roughly 3x the observed noise floor and about two orders of magnitude below a real regression, which moves thousands. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ykargeee-bit
force-pushed
the
feature/ui-kit-pagination-metriccard-confirmation-emptystate
branch
from
October 17, 2026 06:17
842800a to
c584a50
Compare
p3ris0n
approved these changes
Oct 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary Adds four accessible, dependency-free UI-kit primitives to @bc-forge/react, following the existing inline-styles-from-theme-tokens pattern established by Alert and Badge. - Pagination (#1165) ΓÇö previous/next controls, a windowed page list and a page-size . Exports getPageItems, which returns page numbers ascending with ull marking a run collapsed into an ellipsis. Prev/Next disable at the boundaries, and page inputs are clamped so onPageChange can never observe an out-of-range page. - MetricCard / MetricStatBox (#1166) ΓÇö title, large value, delta badge and subtitle. The sign of delta selects the success / danger / neutral tokens, and loading renders a skeleton with �ria-busy. �igint values are stringified rather than coerced through Number. - ConfirmationDialog (#1167) ΓÇö guards destructive actions (burn, revoke role). Confirm stays disabled until the acknowledgement gate passes: a checkbox in checkbox mode, or an exact case-insensitive match of confirmationKeyword in keyword mode. �usy locks both buttons and unbinds Escape so an in-flight transaction cannot be dismissed. Self-contained: own portal, backdrop, focus trap and focus restore. - EmptyState (#1168) ΓÇö the zero-result state for a table, listing or search, with a built-in inline SVG icon, a title, a description and a primary (plus optional secondary) action. ## Notes for the reviewer - ConfirmationDialog deliberately does not depend on a shared Modal primitive ΓÇö it owns its portal, focus trap and Escape handling, so this lands independently. - Page-size changes emit page 1, since the previous offset is meaningless after a resize. - confirmationKeyword defaults to 'CONFIRM' so keyword mode cannot deadlock with a permanently disabled Confirm. - All four components are documented in eact/src/components/COMPONENTS.md with prop tables and examples, and are exported from the package root. ## Verification Nothing here has been machine-verified ΓÇö @testing-library/jest-dom / jest / eslint were not run, as requested. 110 colocated unit tests and 37 Storybook stories were added. ΓÜá∩╕Å Two steps needed before CI is green (both are pre-existing repo constraints, not introduced here): 1. pm ci / pm install ΓÇö no new dependencies, so this should be a no-op, but the lockfile was not regenerated. 2. pm run test:visual:update --workspace @bc-forge/react on the arm64 Playwright image. eact/visual/stories.spec.ts screenshots every story against zero-tolerance baselines with updateSnapshots: 'none', so the new stories have no committed PNGs yet and est:visual will fail until they are generated. Closes #1165 Closes #1166 Closes #1167 Closes #1168