Skip to content

fix(bulma-ui): retry failed avatar src, flatten Avatars fragments, fix RTL overlap - #296

Closed
claude[bot] wants to merge 1 commit into
mainfrom
fix/265-avatars
Closed

claude[bot] wants to merge 1 commit into
mainfrom
fix/265-avatars

Conversation

@claude

@claude claude Bot commented Jul 14, 2026 •

Copy link
Copy Markdown

Pull Request

Description

Fixes the three Avatar/Avatars behavior defects from issue #265 (found by the #257 deep review), plus its drive-by test fix.

  • bulma-ui (@allxsmith/bestax-bulma)
  • create-bestax (create-bestax)
  • docs (@allxsmith/bestax-docs) — avatar.md / avatars.md notes
  • Other (please specify):

1. erroredSrc latch never cleared (Avatar.tsx). The failed-src marker was only ever set, so src="/a.jpg" fails → switch to /b.jpg → switch back to /a.jpg stayed on initials forever with no retry. The error state now resets whenever src changes (React render-time state adjustment — no effect, no extra render commit), making the failure per-URL-attempt instead of per-mount history. Test: fail → switch → switch-back now asserts the img remounts with the original URL.

2. Fragment children broke max and prop injection (Avatars.tsx). React.Children.toArray does not descend into Fragments, so <Avatars max={3}><>{…mapped list…}</></Avatars> counted ONE child: max never clamped, no surplus bubble, and the group size/shape was cloned onto the Fragment and dropped. Fragments are now flattened recursively before counting; flattened elements are re-keyed with their fragment's key as a prefix so children hoisted from different nesting levels can't collide with same-position siblings (test asserts no React duplicate-key warning for the static-avatar + keyed-mapped-list case from the issue).

3. RTL overlap broken (_avatars.scss). The stack overlap used physical margin-left; under dir="rtl" the negative margin pulls avatars apart instead of overlapping. Both the overlap rule and the .is-spaced reset now use logical margin-inline-start. Per the issue's suggestion the other #257 partials were audited: _avatar.scss has no physical direction properties, and _badge.scss's left:/right: usages belong to the named position variants (is-top-right promises a physical corner), so they deliberately stay physical.

Drive-by: the ignores non-element children test now asserts the text node is actually dropped — it previously passed with or without the filter.

Related Issue(s)

Closes #265

Type of Change

  • Bug fix

Checklist

  • My code follows the project style guidelines
  • I have performed a self-review of my code
  • I have added tests that prove my fix is effective (8 new/strengthened assertions — all 8 fail on main, pass with the fixes; includes a compiled-SCSS style suite Avatars.styles.test.tsx pinning the logical property, per the Badge.styles.test.tsx precedent from fix(bulma-ui): fix standalone Badge pointer-events, pulse halo, and falsy content #295)
  • I have added/updated documentation as needed (avatar.md retry note; avatars.md fragment + RTL notes)
  • I have updated Storybook stories as needed (new RTLOverlap story with a dir="rtl" container)
  • All new and existing tests passed (bulma-ui: 3452/3452, coverage 99.6/99.06/99.75/99.81 — above the 99% bar)
  • pnpm gen:catalog run — no catalog change (no API surface change)
  • typecheck, lint, format:check, check:conformance, bulma-ui build all green locally

Additional Context

Implemented directly in-session (not via the claude-fix loop) at the owner's request. RTL verified via the compiled-SCSS assertions and the new Storybook story.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Pohc8xLkdx4gwXkW3xd7up


Generated by Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Avatar images now retry when the image source changes, including when returning to a previously failed URL.
    • Avatar groups now correctly handle nested fragments when counting, limiting, and applying shared properties.
    • Avatar overlap and spacing now work correctly in right-to-left layouts.
  • Documentation

    • Updated Avatar and Avatars documentation to describe image retries, fragment handling, and RTL behavior.

…x RTL overlap

Three Avatar/Avatars defects from the #257 deep review (issue #265):

- Avatar: the erroredSrc latch was never cleared, so switching src away
  and back to a once-failed URL never retried — initials forever. The
  error state now resets whenever src changes (render-time adjustment),
  making failure per-URL-attempt instead of per-mount history.
- Avatars: React.Children.toArray does not descend into Fragments, so a
  fragment wrapper counted as ONE child — max never clamped and the
  group size/shape was cloned onto the fragment and dropped. Fragments
  are now flattened recursively, re-keyed with the fragment's key as a
  prefix to avoid cross-level key collisions.
- _avatars.scss: overlap used physical margin-left, which pulls avatars
  apart instead of overlapping under dir="rtl". Now margin-inline-start
  (both the overlap and the .is-spaced reset). Compiled-SCSS style tests
  pin the logical property; a new RTLOverlap story shows it live.

Drive-by: the 'ignores non-element children' test now asserts the text
node is actually dropped (it previously passed with or without the
filter). Badge's is-top-right/left position variants keep physical
left/right deliberately — those names promise physical corners.

Fixes #265

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pohc8xLkdx4gwXkW3xd7up
@coderabbitai

coderabbitai Bot commented Jul 14, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 5769cb0d-e398-411e-ba42-7bbd9513a44b

📥 Commits

Reviewing files that changed from the base of the PR and between 054772d and 8966a1b.

📒 Files selected for processing (9)
  • bulma-ui/src/components/Avatar.tsx
  • bulma-ui/src/components/Avatars.stories.tsx
  • bulma-ui/src/components/Avatars.tsx
  • bulma-ui/src/components/__tests__/Avatar.test.tsx
  • bulma-ui/src/components/__tests__/Avatars.styles.test.tsx
  • bulma-ui/src/components/__tests__/Avatars.test.tsx
  • bulma-ui/src/scss/components/_avatars.scss
  • docs/docs/api/components/avatar.md
  • docs/docs/api/components/avatars.md

Walkthrough

Avatar retries failed image sources after src changes. Avatars recursively flattens fragments for counting and group prop propagation. Avatar stacking now uses logical margins for RTL layouts, with tests, Storybook coverage, and documentation updates.

Changes

Avatar and Avatars behavior

Layer / File(s) Summary
Avatar image retry behavior
bulma-ui/src/components/Avatar.tsx, bulma-ui/src/components/__tests__/Avatar.test.tsx, docs/docs/api/components/avatar.md
Avatar clears remembered image failures when src changes, retries previously failed URLs, and documents the behavior.
Fragment flattening and group propagation
bulma-ui/src/components/Avatars.tsx, bulma-ui/src/components/__tests__/Avatars.test.tsx
Avatars recursively flattens fragments so max, size, and shape apply consistently, while tests cover nested, keyed, and non-element children.
RTL-aware stacking validation
bulma-ui/src/scss/components/_avatars.scss, bulma-ui/src/components/Avatars.stories.tsx, bulma-ui/src/components/__tests__/Avatars.styles.test.tsx, docs/docs/api/components/avatars.md
Avatar spacing uses margin-inline-start, with compiled-style tests, an RTL Storybook story, and documentation updates.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

Possibly related PRs

  • allxsmith/bestax#257 — Touches the same Avatar retry and Avatars RTL stacking implementation areas.

Suggested reviewers: bestaxbot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main avatar retry, fragment flattening, and RTL overlap fixes.
Description check ✅ Passed The description largely follows the template, covering summary, affected packages, related issue, change type, checklist, and context.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/265-avatars

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://519af4c5.bestax.pages.dev

@claude claude Bot removed the deep-review label Jul 14, 2026
@claude claude Bot closed this Jul 14, 2026
@claude

claude Bot commented Jul 14, 2026

Copy link
Copy Markdown
Author

Closed in favor of an owner-authored PR from the same branch (fix/265-avatars) — no code changes; CI (11/11) and CodeRabbit (zero findings) already passed on 8966a1b.


Generated by Claude Code

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Avatar/Avatars: failed src never retried, Fragment children break max, RTL overlap broken

1 participant