234cfcd: Add onEditStart
and onEditEnd
callbacks for values.
useControls({
value: {
value: 1,
onEditStart: (value, path) => {},
onEditEnd: (value, path) => {},
},
})
Add path
as a second parameter to onChange
callback to mimic onEditXXX
signature.
a2db0e6: Improve buttonGroup
API.
The label is now completely hidden when specifying key that only includes spaces. Previously the label was still rendered, but without text, this caused ugly spacing when using the oneLineLabels
option on the Leva
component.
const [values, set] = useControls(() => ({
Size: 1,
' ': buttonGroup({
'0.25x': () => set({ Size: 0.25 }),
'0.5x': () => set({ Size: 0.5 }),
'1x': () => set({ Size: 1 }),
'2x': () => set({ Size: 2 }),
'3x': () => set({ Size: 3 }),
}),
}))
It is now possible to set the label
via the buttonGroup
arguments by using the alternative API:
const [values, set] = useControls(() => ({
Width: 1,
WidthPresets: buttonGroup({
label: null,
opts: {
'0.25x': () => set({ Size: 0.25 }),
'0.5x': () => set({ Size: 0.5 }),
'1x': () => set({ Size: 1 }),
'2x': () => set({ Size: 2 }),
'3x': () => set({ Size: 3 }),
},
}),
Height: 1,
HeightPresets: buttonGroup({
label: null,
opts: {
'0.25x': () => set({ Size: 0.25 }),
'0.5x': () => set({ Size: 0.5 }),
'1x': () => set({ Size: 1 }),
'2x': () => set({ Size: 2 }),
'3x': () => set({ Size: 3 }),
},
}),
}))
This also allows passing any JSX element as the label beside strings.
It also helps avoiding a bunch of `` labels (where each new one contains one more space).
d0b45de: Add context
argument to onChange
handler.
The context.initial
boolean parameter can be used to identify whether onChange
is invoked initially.
useControls({
value: {
value: 1,
onChange: (value, { initial }) => {
syncValue(value)
if (!initial) {
saveValueOnRemote(value)
}
},
},
})
The context.fromPanel
boolean parameter can be used to identify whether the onChange
invocation is caused by the Leva
component or via the set
function return from the useControl
hook.
const [, set] = useControls(() => ({
value: {
value: 1,
onChange: (value, { initial, fromPanel }) => {
syncValue(value)
if (!initial && !fromPanel) {
// we don't wanna trigger a remote save in case the value has not been updated from the panel
saveValueOnRemote(value)
}
},
},
}))
The context.get
parameter can be used for retrieving the up to date state of the store. This is handy if you need to do some invocations based on all the store values.
const [, set] = useControls(() => ({
value1: 1,
value2: 2,
value3: {
value: 1,
onChange: (value3, { get }) => {
const { value1, value2 } = get()
// calculate something based on value1 and value2
},
},
}))
edc8847: Breaking: change how leva/plugin
exports components.
// before
import { Row, Label, String } from 'leva/plugin'
// after
import { Components } from 'leva/plugin'
const { Row, Label, String } = Components
Feat: add useValue
/ useValues
hooks that let an input query other inputs values.
Feat: normalize
has additional arguments to its signature:
/**
* @path the path of the input
* @data the data available in the store
*/
const normalize = (input: Input, path: string, data: Data)
Feat: sanitize
has additional arguments to its signature:
/**
* @path the path of the input
* @store the store
*/
const sanitize = (
value: any,
settings: Settings,
prevValue: any,
path: string,
store: StoreType
)
Styles: better feedback when dragging number from inner label.
Plugin: add the Plot plugin 📈
import { plot } from '@leva-ui/plugin-plot'
useControls({ y: plot({ expression: 'cos(x)', graph: true, boundsX: [-10, 10], boundsY: [0, 100] }) })