Skip to content

Add new loading indicator#635

Open
braginini wants to merge 1 commit intomainfrom
feature/new-loading-indicator
Open

Add new loading indicator#635
braginini wants to merge 1 commit intomainfrom
feature/new-loading-indicator

Conversation

@braginini
Copy link
Copy Markdown
Contributor

@braginini braginini commented May 8, 2026

Issue ticket number and link

Screen.Recording.2026-05-08.at.16.14.16.mov

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

Docs PR URL (required if "docs added" is checked)

Paste the PR link from https://github.com/netbirdio/docs here:

https://github.com/netbirdio/docs/pull/__

Summary by CodeRabbit

  • Style
    • Redesigned the loading animation with a fresh, updated visual appearance to enhance user experience during application loading states
    • Increased the size of the full-screen loading indicator to improve its visibility and prominence when displayed during application operations

@braginini braginini requested a review from heisbrot May 8, 2026 14:14
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

LoadingIcon refactored from animated <rect> elements to CSS keyframe-driven pulse animation with three <path> shapes. The SVG viewBox expanded from 135x140 to 0 0 919 669. FullScreenLoading's LoadingIcon size increased from 44 to 68.

Changes

Loading Icon Redesign and Integration

Layer / File(s) Summary
SVG Animation Definition
src/assets/icons/LoadingIcon.tsx
Inline <style> defines nb-loader-pulse keyframe animation with scale and opacity transforms applied to the nb-loader-bird class.
SVG Artwork and Animation Binding
src/assets/icons/LoadingIcon.tsx
Animated <g> group wraps three <path> elements replacing previous <rect>-based bars with static SVG paths tied to the pulse animation.
Complete SVG Refactoring
src/assets/icons/LoadingIcon.tsx
SVG viewBox changed to 0 0 919 669, consolidating animation and artwork into a single group structure without <animate> tags.
Component Size Configuration
src/components/ui/FullScreenLoading.tsx
LoadingIcon size prop increased from 44 to 68 to accommodate the redesigned icon dimensions.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • netbirdio/dashboard#555: Both PRs modify the FullScreenLoading component; this PR updates the LoadingIcon size while the related PR changes the component's overall props/API structure.

Suggested reviewers

  • heisbrot

Poem

🐰 A loading bird now pulses with grace,
No more bars dancing—one smooth pace,
Bigger and brighter at size sixty-eight,
CSS keyframes make animation first-rate! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete. It references an asset instead of an issue number, and does not explain why documentation is not needed despite the refactored LoadingIcon being a UI component. Replace the asset link with the actual issue ticket number/URL and provide a brief explanation for why documentation updates are not necessary for this UI component change.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add new loading indicator' directly summarizes the main change: refactoring LoadingIcon to use a new pulse-based SVG animation and updating FullScreenLoading to use it with a larger size.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 feature/new-loading-indicator

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

❤️ Share

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/assets/icons/LoadingIcon.tsx (1)

11-21: ⚡ Quick win

Inline <style> injects a global class into the document on every render

The <style> block is emitted as a DOM node each time LoadingIcon mounts. Multiple simultaneous instances (e.g., skeleton screens, storybook, tests) will accumulate duplicate style tags. More broadly, .nb-loader-bird is a flat global name — any future element using the same class name picks up the pulse animation unintentionally.

Prefer moving the keyframe + class rule to a CSS/SCSS module (or the project's global stylesheet), and import styles from './LoadingIcon.module.css' so the class name is locally scoped.

♻️ Suggested approach (CSS module)

LoadingIcon.module.css:

+@keyframes nb-loader-pulse {
+  0%, 100% { transform: scale(0.85); opacity: 0.35; }
+  50%      { transform: scale(1);    opacity: 1;    }
+}
+.bird {
+  animation: nb-loader-pulse 1.75s ease-in-out infinite;
+  transform-origin: 50% 50%;
+  transform-box: fill-box;
+}

LoadingIcon.tsx:

+import styles from "./LoadingIcon.module.css";
 ...
-      <style>{`
-        `@keyframes` nb-loader-pulse { … }
-        .nb-loader-bird { … }
-      `}</style>
-      <g className={"nb-loader-bird"}>
+      <g className={styles.bird}>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/icons/LoadingIcon.tsx` around lines 11 - 21, The component
LoadingIcon is injecting a <style> tag with global rules (keyframes
nb-loader-pulse and .nb-loader-bird) on every mount which causes duplicate tags
and global namespace collisions; move these declarations into a CSS module
(e.g., create LoadingIcon.module.css containing the `@keyframes` nb-loader-pulse
and a locally-scoped loader class) then update the LoadingIcon component to
import styles from './LoadingIcon.module.css' and replace usages of
"nb-loader-bird" with styles.someClassName so the animation is scoped and the
style tag is no longer emitted at render time.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/ui/FullScreenLoading.tsx`:
- Line 15: The SVG in LoadingIcon currently hardcodes path fill colors so the
parent className="fill-netbird" in FullScreenLoading is dead; update the
LoadingIcon component's <path> elements to use fill="currentColor" (or remove
presentation fill attributes) so the icon inherits color, then change the parent
usage in FullScreenLoading to apply a text color utility (e.g., replace
className="fill-netbird" with className="text-netbird" or otherwise set CSS
color) to control the brand color via CSS-driven theming.

---

Nitpick comments:
In `@src/assets/icons/LoadingIcon.tsx`:
- Around line 11-21: The component LoadingIcon is injecting a <style> tag with
global rules (keyframes nb-loader-pulse and .nb-loader-bird) on every mount
which causes duplicate tags and global namespace collisions; move these
declarations into a CSS module (e.g., create LoadingIcon.module.css containing
the `@keyframes` nb-loader-pulse and a locally-scoped loader class) then update
the LoadingIcon component to import styles from './LoadingIcon.module.css' and
replace usages of "nb-loader-bird" with styles.someClassName so the animation is
scoped and the style tag is no longer emitted at render time.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ad80c4e8-797d-4b66-8438-a54a8ea0bc5a

📥 Commits

Reviewing files that changed from the base of the PR and between dc1adeb and 5be79b9.

📒 Files selected for processing (2)
  • src/assets/icons/LoadingIcon.tsx
  • src/components/ui/FullScreenLoading.tsx

)}
>
<LoadingIcon className="fill-netbird" size={44} />
<LoadingIcon className="fill-netbird" size={68} />
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

fill-netbird is now dead code — the paths' explicit fill attributes block inheritance

Previously, the <rect> elements in LoadingIcon had no explicit fill, so they inherited the fill-netbird color from the parent SVG. The new <path> elements each carry hardcoded fill presentation attributes (#F68330, #F35E32). Presentation attributes contribute to the author level of the cascade with specificity 0, and SVG presentation attributes are overridden by any other style definitions, but they still apply directly to the element and beat inherited values from a parent. As a result, className="fill-netbird" has no visual effect on the rendered bird shapes.

Two paths forward:

Option A — Accept the hardcoded brand palette and drop the dead class:

-      <LoadingIcon className="fill-netbird" size={68} />
+      <LoadingIcon size={68} />

Option B — Restore CSS-driven theming by using currentColor in the paths:

- fill="#F68330"
+ fill="currentColor"

Then control the color via a text-* Tailwind utility on the parent element (SVG fill inherits from CSS color when currentColor is used).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<LoadingIcon className="fill-netbird" size={68} />
<LoadingIcon size={68} />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ui/FullScreenLoading.tsx` at line 15, The SVG in LoadingIcon
currently hardcodes path fill colors so the parent className="fill-netbird" in
FullScreenLoading is dead; update the LoadingIcon component's <path> elements to
use fill="currentColor" (or remove presentation fill attributes) so the icon
inherits color, then change the parent usage in FullScreenLoading to apply a
text color utility (e.g., replace className="fill-netbird" with
className="text-netbird" or otherwise set CSS color) to control the brand color
via CSS-driven theming.

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