Skip to content

fix: button label should use settings.label if provided#606

Open
dinakars777 wants to merge 7 commits intopmndrs:mainfrom
dinakars777:fix/button-label-settings
Open

fix: button label should use settings.label if provided#606
dinakars777 wants to merge 7 commits intopmndrs:mainfrom
dinakars777:fix/button-label-settings

Conversation

@dinakars777
Copy link
Copy Markdown

@dinakars777 dinakars777 commented Mar 20, 2026

Summary

  • Fixes issue where button label from settings.label was being ignored
  • The button now uses settings.label if provided, otherwise falls back to the key name
  • Added label?: string to ButtonSettings type

Fixes

Fixes #528

Changes

  • Modified Button component to prefer settings.label over the key-based label
  • Updated ButtonSettings type to include optional label property

Testing

  • All existing tests pass (18/18)

Summary by CodeRabbit

  • New Features

    • Buttons can show an optional custom label supplied via settings.
  • Bug Fixes

    • Text/string inputs update immediately; number inputs keep commit-on-blur behavior.
    • Improved expand/collapse animations with more accurate height handling and smoother transitions.
    • Numeric inputs no longer reattach parsed suffix to the internal value, improving numeric normalization.

Previously, string inputs only committed changes to the store on blur.
This change makes onUpdate fire on every keystroke for string inputs
only - number inputs retain their original commit behavior (on blur/enter).

Added comment explaining the type !== 'number' guard.

Fixes pmndrs#599
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
leva Ready Ready Preview, Comment Mar 23, 2026 4:59am

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 20, 2026

🦋 Changeset detected

Latest commit: 1077577

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

This PR includes changesets to release 1 package
Name Type
leva Patch

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 20, 2026

📝 Walkthrough

Walkthrough

Button now uses settings.label when provided; ValueInput calls onUpdate only for non-number types; number plugin stops appending suffix to normalized value; useToggle measures content height via ResizeObserver; ButtonSettings type gains an optional label; a changeset was added.

Changes

Cohort / File(s) Summary
Changeset & Types
.changeset/plenty-spies-provide.md, packages/leva/src/types/public.ts
Added a patch changeset entry and extended ButtonSettings with an optional label field.
Button label resolution
packages/leva/src/components/Button/Button.tsx
Button rendering now computes displayLabel from settings.label when present, falling back to the label prop.
Value input update behavior
packages/leva/src/components/ValueInput/ValueInput.tsx
onChange was changed to invoke onUpdate(value) only for non-number types, altering update timing for number inputs.
Number plugin normalization
packages/leva/src/plugins/Number/number-plugin.ts
normalize no longer concatenates the parsed suffix onto the returned value; suffix is retained in settings but value is the clamped numeric.
Toggle height & animation
packages/leva/src/hooks/useToggle.ts
Rewrote expand/collapse logic to use a ResizeObserver, removed timeout-based fallback, unified transitionend cleanup, and improved height application checks.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I hopped through props and tuned a name,
Labels now listen when settings claim,
Numbers shed suffix, inputs wait their cue,
ResizeObserver stretched the view anew,
A tiny rabbit patched the code for you.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The changes in ValueInput, useToggle, and Number plugin appear to be unrelated to the button label fix objective described in issue #528. Remove out-of-scope changes to ValueInput.tsx, useToggle.ts, and number-plugin.ts that are not directly related to fixing the button label issue, or clarify their necessity in the PR description.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main fix: button label should now use settings.label when provided.
Linked Issues check ✅ Passed All coding requirements from issue #528 are met: Button now uses settings.label when provided, ButtonSettings type was extended with label property, and the implementation prefers settings.label over the key-based label.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@codesandbox-ci
Copy link
Copy Markdown

codesandbox-ci bot commented Mar 20, 2026

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 1077577:

Sandbox Source
leva-minimal Configuration
leva-busy Configuration
leva-scroll Configuration
leva-advanced-panels Configuration
leva-ui Configuration
leva-theme Configuration
leva-transient Configuration
leva-plugin-plot Configuration
leva-plugin-bezier Configuration
leva-plugin-spring Configuration
leva-plugin-dates Configuration
leva-custom-plugin Configuration

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 (2)
packages/leva/src/components/Button/Button.tsx (1)

11-20: LGTM! Implementation correctly fixes issue #528.

The logic properly prioritizes settings.label when provided, falling back to the key-based label prop otherwise.

Minor optional simplification: since settings.label is typed as string | undefined, you could use the nullish coalescing operator for slightly cleaner code:

♻️ Optional: Use nullish coalescing
 export function Button({ onClick, settings, label }: ButtonProps) {
   const store = useStoreContext()
-  const displayLabel = settings.label !== undefined ? settings.label : label
+  const displayLabel = settings.label ?? label
   return (
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/leva/src/components/Button/Button.tsx` around lines 11 - 20, In
Button (function Button) simplify the label fallback by replacing the ternary
that reads settings.label !== undefined ? settings.label : label with a nullish
coalescing expression so the component uses settings.label when present and
falls back to label otherwise; update the variable displayLabel in Button to use
the nullish coalescing form to make the intent clearer and more concise.
packages/leva/src/hooks/useToggle.ts (1)

100-105: The height > 0 guard may cause stale wrapper height when content shrinks to zero.

If contentEl shrinks from a positive height to 0 (e.g., all children removed while toggled is true), the ResizeObserver fires but updateHeight() skips the update due to height > 0. The wrapper retains its previous height.

Consider whether content legitimately shrinking to 0 is a supported scenario; if so, handle it explicitly.

Potential approach if shrink-to-zero must be supported
 const updateHeight = () => {
   const { height } = contentEl.getBoundingClientRect()
-  if (ref.style.height !== `${height}px` && height > 0) {
+  if (ref.style.height !== `${height}px`) {
     ref.style.height = `${height}px`
   }
 }

However, this may introduce flicker if height is temporarily 0 during opacity transitions. You may need a debounce or explicit check for the collapsed state.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/leva/src/hooks/useToggle.ts` around lines 100 - 105, The
updateHeight function currently ignores updates when
contentEl.getBoundingClientRect().height is 0 (the height > 0 guard), which
leaves the wrapper's ref.style.height stale when content shrinks to zero; change
updateHeight (used by the ResizeObserver) to explicitly handle a 0 height case
by allowing ref.style.height to be set to "0px" when the measured height is 0 or
when the component is collapsed (check the toggled/expanded state if present),
and if needed debounce or gate the 0px assignment during known
opacity/transition windows to avoid flicker; locate updateHeight, contentEl, ref
and the ResizeObserver callback in useToggle.ts to implement this logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/leva/src/hooks/useToggle.ts`:
- Around line 126-129: When setting ref.style.height after computing const {
height } = contentEl.getBoundingClientRect(), guard against the case where the
inline height already equals `${height}px` so that fixHeight still runs; add a
check comparing ref.style.height to the target string and if they match call
fixHeight() immediately (or schedule via requestAnimationFrame) instead of
relying solely on ref.addEventListener('transitionend', fixHeight, { once: true
}), and also add a short fallback timeout (e.g., setTimeout to call fixHeight
after ~300ms) to ensure fixHeight executes if the transition never fires; update
the code paths around ref.addEventListener, fixHeight, and the block that sets
ref.style.height/contentEl to incorporate these guards.

---

Nitpick comments:
In `@packages/leva/src/components/Button/Button.tsx`:
- Around line 11-20: In Button (function Button) simplify the label fallback by
replacing the ternary that reads settings.label !== undefined ? settings.label :
label with a nullish coalescing expression so the component uses settings.label
when present and falls back to label otherwise; update the variable displayLabel
in Button to use the nullish coalescing form to make the intent clearer and more
concise.

In `@packages/leva/src/hooks/useToggle.ts`:
- Around line 100-105: The updateHeight function currently ignores updates when
contentEl.getBoundingClientRect().height is 0 (the height > 0 guard), which
leaves the wrapper's ref.style.height stale when content shrinks to zero; change
updateHeight (used by the ResizeObserver) to explicitly handle a 0 height case
by allowing ref.style.height to be set to "0px" when the measured height is 0 or
when the component is collapsed (check the toggled/expanded state if present),
and if needed debounce or gate the 0px assignment during known
opacity/transition windows to avoid flicker; locate updateHeight, contentEl, ref
and the ResizeObserver callback in useToggle.ts to implement this logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5ba6bb1b-d14f-4efd-97fa-d6a4f1c090cd

📥 Commits

Reviewing files that changed from the base of the PR and between 402a1e9 and 6c9b8c2.

📒 Files selected for processing (6)
  • .changeset/plenty-spies-provide.md
  • packages/leva/src/components/Button/Button.tsx
  • packages/leva/src/components/ValueInput/ValueInput.tsx
  • packages/leva/src/hooks/useToggle.ts
  • packages/leva/src/plugins/Number/number-plugin.ts
  • packages/leva/src/types/public.ts

- Guard against transitionend not firing when height already matches target
- Update changeset to reflect button label fix
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/leva/src/hooks/useToggle.ts`:
- Around line 114-118: The early return in useToggle (the firstRender.current
branch) prevents the ResizeObserver from being created when toggled starts true;
change the flow so you still call updateHeight() and then proceed to
create/register the ResizeObserver (or call the existing resize observer setup
code) even on first render, but keep the animation/skipping logic gated by
firstRender.current so the initial render doesn't animate; adjust the code
around firstRender.current, updateHeight, and the ResizeObserver setup (or
setupResizeObserver function) to ensure the observer is always attached while
preserving the no-animation-on-first-render behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b6e4b6f7-757e-491d-adb7-ccccc907ff51

📥 Commits

Reviewing files that changed from the base of the PR and between 6c9b8c2 and f097864.

📒 Files selected for processing (2)
  • .changeset/plenty-spies-provide.md
  • packages/leva/src/hooks/useToggle.ts
✅ Files skipped from review due to trivial changes (1)
  • .changeset/plenty-spies-provide.md

@dinakars777
Copy link
Copy Markdown
Author

Thanks for the review! Added transitionend guard to handle edge case when height already matches target. Updated changeset. Resolved.

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.

Button element does not pass "label" property correctly

1 participant