![preview](https://private-user-images.githubusercontent.com/3682284/243087287-554b6c4f-61e0-4a22-b3bb-931f0267a632.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ5NjQ2NDUsIm5iZiI6MTcyNDk2NDM0NSwicGF0aCI6Ii8zNjgyMjg0LzI0MzA4NzI4Ny01NTRiNmM0Zi02MWUwLTRhMjItYjNiYi05MzFmMDI2N2E2MzIucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDgyOSUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDA4MjlUMjA0NTQ1WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MmUxYzJiN2FjMjlmZWJmOWM0MzI2ZjBiY2NkNDE0ZmQxNzQwOWMwODAwMWY0YWZlYzczNWFjMTExMzA1MTZkMSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.AnDZ1ipkKoIV5Yh5KN2G1U2oy60UUq1Dm_OatMFwpV0)
Enhance your React application experience with react-tweakpane
!
This library introduces a hook-based React wrapper for Tweakpane, a compact pane library for fine-tuning parameters and monitoring value changes. π
For detailed information, be sure to visit the Tweakpane documentation.
- Smart Types: Intelligent interpretation of variable types.
- Prop Change Listener: Observes changes of passed props.
- Memoization: Functions and objects passed into hooks do not cause re-renders or updates unless changed.
- Re-rendering Control: Grants you granular control over component re-rendering in response to value changes.
In Development βοΈ: Please note,
react-tweakpane
is under active development. As such, some features might be currently missing. We appreciate your patience and encourage your feedback as we continue to improve and expand this library! π
You can install the necessary packages using the following commands:
With npm:
npm install tweakpane @tweakpane/core react-tweakpane
With yarn:
yarn add tweakpane @tweakpane/core react-tweakpane
Here's a basic example of how you can integrate Tweakpane in your React app:
const pane = useTweakpane({ position: { x: 0, y: 0, z: 0 } })
// With state, change will trigger re-render
const [position, setPosition] = usePaneInput(pane, 'position')
// Without react-state, changes would not trigger re-render
usePaneInput(pane, 'position', (event) => {
const { x, y, z } = event.value
// Do what you need
})
// onChange function is memoized, so you can rest easy! π
usePaneInput(pane, 'position', (event) => {
const { x, y, z } = event.value
// Do what you need
})
// It is still possible to set value manually
const [, setValue] = usePaneInput(pane, 'position', (event) => {
const { x, y, z } = event.value
// Do what you need
})
To organize your pane with folders, use same hooks as regular, but pass folder reference instead of pane as first argument
const folder = usePaneFolder(pane, {
title: 'Box Settings',
})
const [pos] = usePaneInput(folder, 'position')
const [rotation] = usePaneInput(folder, 'rotation')
const [scale] = usePaneInput(folder, 'scale')
Pass in Tweakpane options to customize your pane and inputs:
// Tweakpane options
const pane = useTweakpane(
{
position: { x: 0, y: 0, z: 0 },
},
// Default Tweakpane params
{
title: 'Scene Settings',
expanded: false,
}
)
// Input Options
const [value, setValue] = usePaneInput(folder, 'value', {
label: 'Pos',
value: {
min: -10,
max: 10,
},
})
You can add controls as rows to the pane. Tweakpane calls each row a βbladeβ. Utilize various blades to enhance your pane:
// Slider Blade
const [time] = useSliderBlade(pane, {
label: 'Time',
value: 0.6,
min: 0,
max: 1,
step: 0.01,
format: (value) => value.toFixed(2),
})
// List blade
const [fruit] = useListBlade(pane, {
label: 'Fruit',
options: [
{
text: 'Apple π',
value: 'apple',
},
{
text: 'Orange π',
value: 'orange',
},
{
text: 'Banana π',
value: 'banana',
},
],
value: 'apple'
})
// Text blade with number input & rounding
const [value, setValue] = useTextBlade(pane, {
label: 'Title',
value: 0.35,
parse: (value) => Number(value),
format: (value) => value.toFixed(2),
})
While react-tweakpane
provides a more React-oriented interface for many common Tweakpane use cases, you still have direct access to the underlying Tweakpane object for advanced use cases not yet supported by our library.
This means that you can use any Tweakpane feature directly, as shown in this example with monitors:
const pane = useTweakpane({
/* ... */
})
useEffect(() => {
const tweakpane = pane.current.instance!
tweakpane.addMonitor(PARAMS, 'wave', {
view: 'graph',
min: -1,
max: 1,
})
}, [])
Take a peek at what we've already made so far and our future plans for react-tweakpane
:
- Core Functionality
- Inputs Hooks
- Folders Support
- Blades Support
- Monitor Support: We're working on adding support for monitors to make real-time monitoring more seamless.
- Separators
- Tabs
- Buttons
- JSX Syntax: We have plans to implement JSX syntax for a more intuitive and React-friendly experience.
Please note that these are our current plans and might change based on feedback and development progress. We highly encourage your ideas and contributions in shaping the future of react-tweakpane
.
Stay tuned for updates! π
Have a suggestion or a feature request? Don't hesitate to open an issue or PR!
Both react-tweakpane
and useTweaks
aim to provide React-friendly interfaces for Tweakpane. However, they have some differences, and useTweaks
seems not to be actively maintained at present. Here are some key aspects where react-tweakpane
stands out:
- Structure: react-tweakpane syntax aims to mirror conventional React patterns and align closely with the original library's design.
- Feature Support:
react-tweakpane
has a different feature set. It supports blades but is currently missing buttons and separators. - Direct Tweakpane Object Access:
react-tweakpane
gives you direct access to the underlying Tweakpane object, allowing for more advanced use cases. - Control Over Re-rendering:
react-tweakpane
gives you more control on when your component re-renders after values change, potentially enhancing performance.
This project is open source and available under the MIT License
We're working hard to integrate more Tweakpane features directly into react-tweakpane
, so stay tuned for future updates! π