feat(#48): redesign and implement loader animation (skeleton loader family)#102
feat(#48): redesign and implement loader animation (skeleton loader family)#102RudoiDmytro wants to merge 1 commit into
Conversation
…rchitecture, epics) Exclude specs/ from markdownlint: prose artifacts with wide tables, not code-grade markdown.
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
1 issue found across 6 files
Confidence score: 5/5
- In
specs/planning-artifacts/loader-animation/README.md, the summary claims FR1–FR25 while the PRD includes FR26–FR28, which could mislead reviewers about scope and cause focus-management/Storybook preview requirements to be missed later—update the README coverage line to include FR26–FR28 before or immediately after merge.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="specs/planning-artifacts/loader-animation/README.md">
<violation number="1" location="specs/planning-artifacts/loader-animation/README.md:22">
P3: README summary understates PRD FR coverage: says FR1–FR25 but PRD defines FR26, FR27, FR28 (focus management + Storybook previews).</violation>
</file>
Architecture diagram
sequenceDiagram
participant User as User
participant App as React App Shell
participant AuthPage as Auth Page
participant FormSection as FormSection (lazy chunk)
participant UIForm as UIForm / SubmitControls
participant UIButton as UIButton
participant LoaderFamily as Loader Family (L1-L5)
participant SharedMotion as Shared Motion Module (base/styles.ts)
participant ScreenReader as Screen Reader
participant VisualTest as Visual Snapshot Test
Note over User,VisualTest: CURRENT STATE BEFORE PR (fragmented loading)
User->>App: Navigate to auth page
App->>AuthPage: Mount
AuthPage->>AuthPage: <Suspense fallback={<AuthSkeleton/>}>
Note over AuthPage: Renders region landmark on decorative content
AuthPage-->>User: Shimmer skeleton (animated, no reduced-motion support)
AuthPage->>FormSection: Lazy load
User->>UIForm: Fill form, press submit
UIForm->>UIButton: Set disabled=true
UIForm->>UIForm: Show <CircularProgress size={70}> beside button
Note over UIForm: Button goes flat gray (#E1E7EA) + detached spinner
Note over UIForm: White text on #E1E7EA = ~1.25:1 contrast failure
UIButton-->>User: Disabled button + spinner
User->>ScreenReader: Focus / navigate
ScreenReader->>AuthPage: Reads region landmark on decorative skeleton
ScreenReader->>UIForm: Hears disabled button, no loading feedback from spinner
VisualTest->>VisualTest: emulateMedia({ reducedMotion: 'reduce' })
VisualTest->>AuthPage: Takes snapshot - captures static fallback (not animated shimmer)
Note over User,VisualTest: Silent waits with no loader at all
User->>FormSection: Switch login/register form
FormSection->>UIButton: Set disabled=true (no spinner, no loader)
UIButton-->>User: Just disabled switch - no pending feedback
User->>FormSection: Click retry on registration error
FormSection->>UIButton: Set disabled=true (inside role="alert" live region)
UIButton-->>User: Disabled button, no loading signal
Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.
Re-trigger cubic
|
|
||
| | # | Document | What it covers | | ||
| | --- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | | ||
| | 1 | [`prd.md`](./prd.md) | Goals, personas, FR1–FR25 / NFR1–NFR16, acceptance criteria mapped to the issue | |
There was a problem hiding this comment.
P3: README summary understates PRD FR coverage: says FR1–FR25 but PRD defines FR26, FR27, FR28 (focus management + Storybook previews).
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At specs/planning-artifacts/loader-animation/README.md, line 22:
<comment>README summary understates PRD FR coverage: says FR1–FR25 but PRD defines FR26, FR27, FR28 (focus management + Storybook previews).</comment>
<file context>
@@ -0,0 +1,54 @@
+
+| # | Document | What it covers |
+| --- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
+| 1 | [`prd.md`](./prd.md) | Goals, personas, FR1–FR25 / NFR1–NFR16, acceptance criteria mapped to the issue |
+| 2 | [`ux-design.md`](./ux-design.md) | Motion/timing scale, reduced-motion strategy, the 5 loader spec cards, L2 deep-dive, WCAG mapping |
+| 3 | [`architecture.md`](./architecture.md) | Shared motion module, the 5 `UI*` components, the submit-button refactor, DRY/complexity/perf/testing strategy, migration plan |
</file context>
| | 1 | [`prd.md`](./prd.md) | Goals, personas, FR1–FR25 / NFR1–NFR16, acceptance criteria mapped to the issue | | |
| | 1 | [`prd.md`](./prd.md) | Goals, personas, FR1–FR28 / NFR1–NFR16, acceptance criteria mapped to the issue | |
Summary
Closes #48. Redesigns the CRM's fragmented loading experience (disabled gray submit button +
detached 70px
CircularProgress, inconsistent loaders elsewhere, noprefers-reduced-motion,failing disabled-label contrast) around one skeleton-based loader family of five types that
share the existing CSS shimmer as a single motion source-of-truth.
This PR ships in two stages, both landing here:
specs/planning-artifacts/loader-animation/Planning suite (read in this order)
prd.mdux-design.mdarchitecture.mdUI*components, submit-button refactor, DRY/complexity/perf/testing strategy, migration planepics-and-stories.mdThere is intentionally no product brief: for this scoped brownfield enhancement the GitHub
issue is the analysis-phase artifact, and the PRD's Overview/Context absorbs it.
The loader family
UI*)UISkeletonPlaceholderUISubmitLoadingButtonUIInlineLoaderUISectionLoaderUIProgressBarAll five inherit one motion source, one
prefers-reduced-motioncontract, and oneaccessible-status primitive, so the family stays within the jscpd DRY gate, the
rust-code-analysis complexity caps, and the auth-page mobile Lighthouse budget
(pure CSS, no new dependencies). Each loader ships a co-located Storybook preview
covering animated and reduced-motion states.
Repo plumbing
.markdownlintignorenow excludesspecs/— prose planning artifacts with widetables, not code-grade markdown.
make lint-mdpasses; the full pre-commit gate(format + lint + all unit tests) ran green on commit.
Summary by cubic
Adds the planning suite for a unified skeleton loader family (five types) to replace inconsistent loaders across the app, per issue #48. Also updates
.markdownlintignoreto excludespecs/.Written for commit 40901a7. Summary will update on new commits.