Skip to content

Conversation

@myers
Copy link
Contributor

@myers myers commented Oct 15, 2025

Add headless mode entry point

This PR adds a new leva/headless entry point that enables using Leva's state management without automatically rendering the default UI panel. This is useful for building custom UIs in WebXR environments where you can use the DOM or React Three Fiber using 3d controls, or any scenario where you want Leva's hooks without the HTML controls.

What's New

New entry point: leva/headless

  • Exports useControls wrapper that auto-injects headless: true
  • No default Leva panel renders when using this import
  • Full backward compatibility - existing code unchanged

Convenience hooks for building custom UIs:

  • useLevaInputs() - Get array of all inputs with metadata
  • useLevaTree() - Get folder tree structure
  • useLevaInput(path) - Control specific input with full methods

Demo: Added leva-headless demo showing custom UI controls built from input metadata

Implementation Details

  • Added headless parameter to HookSettings type
  • Modified useRenderRoot call to skip when headless: true
  • Exported parseArgs utility to reduce code duplication
  • Headless wrapper reuses shared parsing logic (67 lines vs 87 lines of duplicated conditionals)

Example Usage

import { useControls, useLevaInputs } from 'leva/headless'

function MyCustomUI() {
  // Manages state without rendering default panel
  const values = useControls({
    speed: { value: 1, min: 0, max: 10 },
    color: '#ff0055',
    enabled: true,
  })

  // Get metadata to build your own UI
  const inputs = useLevaInputs()

  return (
    <div>
      {inputs.map(({ path, input }) => (
        <YourCustomControl key={path} path={path} />
      ))}
    </div>
  )
}

@changeset-bot
Copy link

changeset-bot bot commented Oct 15, 2025

🦋 Changeset detected

Latest commit: 05d96e5

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

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

@vercel
Copy link

vercel bot commented Oct 15, 2025

@myers is attempting to deploy a commit to the Poimandres Team on Vercel.

A member of the Team first needs to authorize it.

@codesandbox-ci
Copy link

codesandbox-ci bot commented Oct 15, 2025

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 05d96e5:

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

@myers
Copy link
Contributor Author

myers commented Oct 31, 2025

@gsimone I'm glad to see some of my PR's getting merged. I would really love this one to get merged. Do you have any thoughts on it?

@gsimone
Copy link
Member

gsimone commented Oct 31, 2025

@myers I'll take a proper look once I finished setting up tooling so we can start merging stuff more aggressively!

@myers
Copy link
Contributor Author

myers commented Nov 1, 2025

@gsimone I have a fix for the global panel not being removed when switching between headless/headed mode. I wasn't thinking of allowing a switch like this for my use case. What I was shooting for was using this in WebXR with a uikit panel, where you can't use HTML.

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