Skip to content

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

Closed
allxsmith wants to merge 1 commit into
mainfrom
fix/265-avatars
Closed

allxsmith wants to merge 1 commit into
mainfrom
fix/265-avatars

Conversation

@allxsmith

@allxsmith allxsmith commented Jul 14, 2026 •

Copy link
Copy Markdown
Owner

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. Supersedes #296 (same branch/commit, closed for authorship).

  • 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 commit), making the failure per-URL-attempt instead of per-mount history. Test: fail → switch → switch-back 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. CI (11/11) and CodeRabbit (zero findings) already passed on this exact commit under #296.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Pohc8xLkdx4gwXkW3xd7up


Generated by Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Avatar images now retry loading when the image source changes, including previously failed URLs.
    • Avatar groups correctly count and display avatars wrapped in fragments.
    • Avatar overlap styling now works correctly in both left-to-right and right-to-left layouts.
  • Documentation

    • Clarified image fallback, fragment handling, compound usage, and right-to-left layout 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: e20fc71a-960e-4224-92d8-0518dd32764c

📥 Commits

Reviewing files that changed from the base of the PR and between f9e43cd 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 image sources after src changes. Avatars now flattens fragments for counting and prop propagation, while overlap styling uses logical margins for RTL layouts. Tests, Storybook coverage, and documentation were added or updated.

Changes

Avatar component behavior

Layer / File(s) Summary
Retry failed image sources
bulma-ui/src/components/Avatar.tsx, bulma-ui/src/components/__tests__/Avatar.test.tsx, docs/docs/api/components/avatar.md
Avatar resets the remembered failure when src changes, allowing previously failed URLs to retry; documentation and tests cover the behavior.
Flatten fragment-wrapped avatars
bulma-ui/src/components/Avatars.tsx, bulma-ui/src/components/__tests__/Avatars.test.tsx
Avatars recursively flattens fragments, preserves distinct keys, counts nested avatars for max, and propagates group props through fragments.
RTL-safe overlap styling
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
Overlap and spaced styles use margin-inline-start, with RTL Storybook coverage, compiled CSS assertions, and updated usage documentation.

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

Possibly related PRs

  • allxsmith/bestax#257: Updates related Avatar error-state handling, Avatars child processing, and RTL-safe overlap offsets.

Suggested reviewers: bestaxbot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main fixes: avatar retry logic, fragment flattening, and RTL overlap support.
Description check ✅ Passed The description follows the template well, covering affected packages, issue reference, change type, checklist, and additional 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
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch fix/265-avatars

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


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

Copy link
Copy Markdown
Owner Author

Closing: #297 merged the same three #265 fixes (Avatar src retry, Fragment flattening, RTL logical margins) at 03:57 and released as 5.4.2 — this branch was a parallel implementation and now conflicts. The two small extras here that #297 didn't include (avatar.md/avatars.md notes, a compiled-SCSS style test pinning margin-inline-start) can ride along with a future Avatar-touching PR if wanted.


Generated by Claude Code

@allxsmith allxsmith closed this Jul 14, 2026
@allxsmith
allxsmith deleted the fix/265-avatars branch July 31, 2026 04:46
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

2 participants