Skip to content

feat(BrandLoader): add branded loading indicator - #6932

Open
seany-amp wants to merge 3 commits into
mainfrom
feat/brand-loader
Open

feat(BrandLoader): add branded loading indicator#6932
seany-amp wants to merge 3 commits into
mainfrom
feat/brand-loader

Conversation

@seany-amp

@seany-amp seany-amp commented Jul 24, 2026

Copy link
Copy Markdown

Why

Elevating loading state with a branded, motion-first experience—because pulsing grey boxes needed an iteration to spark joy.

Codesandbox

What

🆕 Add BrandLoader with small, medium and large sizes and three speed presets.
🆕 Animate the official Ensō SVG with accessible status semantics and reduced-motion support.
🆕 Add unit tests, Storybook examples, documentation and Chromatic stickersheets.
🔧 Publicly export BrandLoader and add a minor @kaizen/components changeset.

Verification

✅ Components TypeScript check passed.
✅ All 1,113 component tests passed, including 9 BrandLoader tests.
✅ CSS, TypeScript and formatting checks passed.

Provide a scalable Ensō loader for prominent page and section loading states.

Co-authored-by: Cursor <cursoragent@cursor.com>
@pip-the-concierge

pip-the-concierge Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

🤖 Agent Workflows

  • PR Review — AI-powered code review — ✅ Complete

    Run #6841 — ✅ 6m 46s
    Metric Value
    Duration 6m 46s
    Model Opus
    Turns 22
    Tokens 78,719

@changeset-bot

changeset-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c1778e0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@kaizen/components Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pip-the-concierge-via-chinmina pip-the-concierge-via-chinmina Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This PR adds a well-crafted BrandLoader component to the Kaizen design system. It animates Culture Amp's Ensō SVG using an SVG mask-based stroke-dashoffset reveal technique, with proper accessibility semantics (role="status", required accessibilityLabel, VisuallyHidden), reduced-motion support, and reversed-colors context integration. The implementation follows current repo guidelines — using className (per AGENTS.md preference for new components), logical CSS properties (inline-size/block-size), and stickersheet stories for testing. Clean, well-structured code with no bugs or security issues found.

For reviewers

Reading order:

  1. packages/components/src/Loading/BrandLoader/BrandLoader.tsx — public API surface (props, a11y pattern)
  2. packages/components/src/Loading/BrandLoader/subcomponents/BrandLoaderIcon.tsx — SVG mask animation technique and useId usage
  3. packages/components/src/Loading/BrandLoader/BrandLoader.module.css — animation keyframes, sizing tokens, reduced-motion handling

Key questions:

  • The @keyframes paint block lives outside @layer kz-components (line 68 of the CSS) — is that intentional for layer specificity, or should it be nested inside the layer for consistency with the rest of the design system?
  • stroke-dashoffset: 0 in the prefers-reduced-motion rule reveals the full Enso statically — is that the desired brand representation, or should the SVG hide entirely when motion is reduced?
  • The restProps spread is placed before role="status" in the JSX, so a consumer cannot accidentally override role — worth confirming this ordering is deliberate as an a11y safeguard.

4 Low-signal findings hidden

click to expand
  • packages/components/src/Loading/BrandLoader/BrandLoader.tsx: Uses className instead of classNameOverride (unlike Loading siblings) — rejected because AGENTS.md explicitly prefers className on new components and ADR-0003 confirms classNameOverride is being phased out
  • packages/components/src/Loading/BrandLoader/BrandLoader.module.css: stroke: white is a hardcoded color literal — rejected because this is inside an SVG <mask> where white is a luminance value meaning "fully reveal", not a brand color
  • packages/components/src/Loading/BrandLoader/: No .spec.tsx unit test file despite PR description claiming "unit tests" — rejected because AGENTS.md §8 explicitly says stickersheet stories are the correct test for presentational components, and sibling LoadingSpinner follows the same pattern
  • packages/components/src/Loading/BrandLoader/BrandLoader.module.css: Uses inline-size/block-size while LoadingSpinner uses width/height — rejected because AGENTS.md §7 mandates logical properties for new code; BrandLoader is correct, LoadingSpinner is legacy

generated using the pr-review workflow in 22 turns
give feedback with reactions 👍 👎

@seany-amp
seany-amp marked this pull request as ready for review July 24, 2026 04:40
@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

✨ Here is your branch preview! ✨

Last updated for commit c1778e0: prettier

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.

1 participant