Skip to content

feat: add DocumentProgressCard component#338

Open
interacsean wants to merge 4 commits into
mainfrom
feat/core/784-document-progress-card
Open

feat: add DocumentProgressCard component#338
interacsean wants to merge 4 commits into
mainfrom
feat/core/784-document-progress-card

Conversation

@interacsean

@interacsean interacsean commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds DocumentProgressCard — a presentational card for a transactional document's fulfilment / lifecycle state: a derived completion percentage, a stacked progress bar, and a received / returned / yet-to-receive legend. Ported from the omakase FulfilmentRate component as a view-only, props-driven component (no data-fetching or domain logic).

Implements tailor-inc/platform-planning#784 (Document Progress Card), AppShell v1.6.0. Matches the Figma design.

Screenshot

image

API

<DocumentProgressCard
  received={{ value: 12 }}
  returned={{ value: 2 }}
  yetToReceive={{ value: 28 }}
/>
  • Three opinionated buckets — received / returned / yetToReceive — each { value, label?, color? } with per-bucket label/color defaults (indigo / pink / neutral).
  • Percentage is derived, not passed: received / (received + yetToReceive). returned is a subset of received, so it doesn't change the denominator. Pass returnedCountsAsComplete={false} to subtract returns from progress.
  • title defaults to "Fulfilment rate". Curated color palette (indigo/pink/green/amber/red/blue/neutral).
  • Bar fills with a net-received segment + a returned segment over a muted track; the unfilled remainder represents yet-to-receive.

Changes

  • packages/core/src/components/document-progress-card/ — component (Pattern C), types.ts, index.ts, tests
  • Public export from packages/core/src/index.ts (minimal surface: component + Props type)
  • docs/components/document-progress-card.md, catalogue entry, changeset (minor)
  • examples/vite-app/dashboard/document-progress showcase page + sidebar link

Testing

  • 17 tests (12 behavioral + 5 snapshot); full suite: type-check 8/8, lint 0 errors, 1184 tests, fmt clean
  • Verified visually in the vite example (showcase page + record-detail right rail)

🤖 Generated with Claude Code

interacsean and others added 4 commits June 27, 2026 11:00
A presentational card for a transactional document's fulfilment state:
a derived completion percentage, a stacked progress bar, and a
received / returned / yet-to-receive legend. Ported from the omakase
FulfilmentRate component as a view-only, props-driven component — no
data-fetching or domain logic.

Each bucket takes { value, label?, color? } with per-bucket defaults.
Percent is derived as received / (received + yetToReceive); pass
returnedCountsAsComplete={false} to subtract returns from progress.

Includes behavioral + snapshot tests, docs, catalogue entry, and a changeset.

Refs tailor-inc/platform-planning#784

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a /dashboard/document-progress example page demonstrating the
component's states (empty, partial, returns-subtracted, complete,
relabelled/custom-colors, returns-heavy) and a sidebar nav link.

Refs tailor-inc/platform-planning#784

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adversarial review surfaced two ways the bar could contradict the
header percentage:

- With returnedCountsAsComplete={false}, the header showed
  (received − returned)/total but the bar still filled received/total.
  The returned segment is now part of the colored fill only when it
  counts as complete, so the fill always equals the header percentage.
- When returned > received, the net-received clamp left a returned
  segment wider than the header implied. returned is now clamped to
  received before deriving the breakdown.

Also sanitize incoming amounts (non-finite/negative → 0) so invalid
input can't render NaN/negative figures in the legend or break the bar.

Adds tests for both consistency cases and sanitization; updates docs
and the affected snapshot.

Refs tailor-inc/platform-planning#784

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Treat the bar as a composition rather than a pure progress fill: it
always renders a net-received segment (received − returned) followed by
a returned segment, in both modes. The header percentage maps onto the
net-received segment, plus the returned segment when
returnedCountsAsComplete is true.

This keeps returned items visible in the bar even when they're excluded
from the rate (returnedCountsAsComplete={false}), matching the Figma /
omakase intent, while the net-received segment still equals the header.

Retains the returned≤received clamp and input sanitization. Updates the
affected test, snapshot, and docs.

Refs tailor-inc/platform-planning#784

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@interacsean interacsean marked this pull request as ready for review June 27, 2026 10:58
@interacsean interacsean requested a review from a team as a code owner June 27, 2026 10:58
@IzumiSy

IzumiSy commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

/review

@github-actions

Copy link
Copy Markdown
Contributor

🚀 API Design Review has started processing this issue comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants