Skip to content

refactor(ui): re-pull label, textarea, separator and skeleton from the registry - #38302

Merged
yuneng-berri merged 1 commit into
litellm_internal_stagingfrom
litellm_strip_forwardref_from_cli_primitives
Aug 26, 2026
Merged

refactor(ui): re-pull label, textarea, separator and skeleton from the registry#38302
yuneng-berri merged 1 commit into
litellm_internal_stagingfrom
litellm_strip_forwardref_from_cli_primitives

Conversation

@yuneng-berri

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

How it solves it:

  • Re-pull each from base-vega, which drops the wrapper and its displayName
  • Picked these four because ref plumbing is their only divergence from upstream
  • Add the missing Textarea case to the existing ref test

User Flow

This is a no-op refactor, so the two lists are identical by design. The primitives render the same markup and still hand their ref to the DOM node, so react-hook-form keeps focusing the right field

Before: an admin fills in a form that has a required textarea and leaves it blank

  1. They open http://localhost:4000/ui/?page=vector-stores and click Create Vector Store
  2. They submit with the description empty and the form scrolls to and focuses that textarea
  3. They fill it in and the store is created

After: the same admin sees exactly the same three things

  1. They open http://localhost:4000/ui/?page=vector-stores and click Create Vector Store
  2. They submit with the description empty and the form scrolls to and focuses that textarea
  3. They fill it in and the store is created

Relevant issues

Linear ticket

Pre-Submission checklist

  • I have added meaningful tests
  • The handful of test files covering my change pass locally
  • My PR passes all required CI/CD checks (e.g., lint, schema.d.ts sync check, etc.)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review

Screenshots / Proof of Fix

Setup: start the proxy with python litellm/proxy/proxy_cli.py --config litellm/proxy/dev_config.yaml --detailed_debug --reload, then run npm run dev in ui/litellm-dashboard and sign in at http://localhost:3000

Before (e300822)

Textarea keeps its ref, so a blank required field still gets focused

  1. Open http://localhost:3000/?page=vector-stores and click Create Vector Store
  2. Submit with the description left empty, and screenshot the textarea taking focus with its error
  3. Switch the theme toggle to dark and screenshot the same field

Label, Separator and Skeleton render unchanged

  1. Open http://localhost:3000/?page=api-keys and screenshot the table while its skeleton rows are still showing
  2. Open any key's detail drawer and screenshot the labels and divider lines

After (d2aea2d)

Textarea keeps its ref, so a blank required field still gets focused

  1. Open http://localhost:3000/?page=vector-stores and click Create Vector Store
  2. Submit with the description left empty, and screenshot the textarea taking focus with its error
  3. Switch the theme toggle to dark and screenshot the same field

Label, Separator and Skeleton render unchanged

  1. Open http://localhost:3000/?page=api-keys and screenshot the table while its skeleton rows are still showing
  2. Open any key's detail drawer and screenshot the labels and divider lines

Type

🧹 Refactoring

Caveats (if any)

Low

  • Seven other primitives still carry forwardRef: avatar, breadcrumb, card, chart, combobox, input, table. Each has also drifted from upstream on its class strings, so re-pulling them is a visual change and belongs in its own PR
  • ui/ui-loading-spinner.tsx has one too, but it is not a registry item and is already slated for replacement by a much smaller local Spinner

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

…e registry

These four primitives still wrapped their body in React.forwardRef, which
the dashboard has not needed since it moved to React 19: a function
component receives ref as an ordinary prop and the existing {...props}
spread already hands it to the DOM node.

Re-pulling each from base-vega drops the wrapper and its displayName.
These four were picked because the ref plumbing is their only divergence
from current upstream, so the class strings, data-slot values and exports
are untouched and nothing renders differently. The other seven primitives
that still carry forwardRef have also drifted on their class strings, so
re-pulling them would ship a visual change alongside the cleanup and they
are left alone here.

Textarea is the one with real ref call sites, roughly seventeen of them
through react-hook-form's field.ref, and ref-forwarding.test.tsx did not
cover it. Add that case next to the Label, Separator and Skeleton ones
already there.
@greptile-apps

greptile-apps Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR replaces four legacy React.forwardRef wrappers with React 19 ref-as-prop function components while preserving their rendered elements, props, classes, and ref behavior.

  • Converts Label, Separator, Skeleton, and Textarea to plain function components.
  • Removes obsolete explicit displayName assignments.
  • Adds the previously missing Textarea DOM-ref regression test.

Confidence Score: 5/5

The PR appears safe to merge with ref behavior preserved and directly covered for every changed primitive.

The dashboard uses React 19, each component keeps ref in its spread props, and the tests verify that all four refs resolve to their rendered DOM elements.

Important Files Changed

Filename Overview
ui/litellm-dashboard/src/components/ui/label.tsx Replaces the forwardRef wrapper with a React 19-compatible function while continuing to spread the ref and other props onto the label.
ui/litellm-dashboard/src/components/ui/ref-forwarding.test.tsx Adds a Textarea case to the existing DOM-ref tests without weakening the Label, Separator, or Skeleton assertions.
ui/litellm-dashboard/src/components/ui/separator.tsx Converts the Base UI separator wrapper to ref-as-prop while preserving orientation, styling, attributes, and primitive props.
ui/litellm-dashboard/src/components/ui/skeleton.tsx Simplifies the skeleton to a plain function component while preserving its DOM structure, classes, and prop forwarding.
ui/litellm-dashboard/src/components/ui/textarea.tsx Converts Textarea to React 19 ref-as-prop semantics while preserving the textarea DOM node and react-hook-form ref contract.

Reviews (1): Last reviewed commit: "refactor(ui): re-pull label, textarea, s..." | Re-trigger Greptile

@yuneng-berri
yuneng-berri enabled auto-merge August 26, 2026 06:03
@yuneng-berri
yuneng-berri merged commit 14ead1b into litellm_internal_staging Aug 26, 2026
75 checks passed
@yuneng-berri
yuneng-berri deleted the litellm_strip_forwardref_from_cli_primitives branch August 26, 2026 06:05
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.

2 participants