import React from 'react' import { Meta } from '@storybook/react' import Reset from './components/decorator-reset' import { Half2Icon, OpacityIcon, DimensionsIcon } from '@radix-ui/react-icons' import { folder, useControls, LevaInputs } from '../src' export default { title: 'Misc/Input options', decorators: [Reset], } as Meta export const LabelAndIcon = () => { const values = useControls({ string: { value: 'hello', label: 'My string' }, color: { value: '#f00', label: }, opacity: { value: 0.5, label: }, size: { value: { width: 200, height: 300 }, label: }, }) return (
{JSON.stringify(values, null, '  ')}
) } export const Hint = () => { const values = useControls({ color: { value: '#f00', hint: 'Used for important content' }, position: { value: [0, 0, 0], hint: 'Position of the object relative to the screen' }, }) return (
{JSON.stringify(values, null, '  ')}
) } export const Render = () => { const values = useControls({ show: { value: true, label: 'Show color' }, color: { value: '#fff', render: (get) => get('show') }, show2: { value: false, label: 'Show folder' }, folder: folder( { number: 1, string: { value: 'shown if `number >= 1`', render: (get) => get('folder.number') >= 1, }, }, { render: (get) => get('show2') } ), }) return (
{JSON.stringify(values, null, '  ')}
) } export const Optional = () => { const values = useControls({ color: { value: '#f00', optional: true }, vector: { value: [0, 0, 0], optional: true, disabled: true }, }) return (
{JSON.stringify(values, null, '  ')}
) } function A() { const renderRef = React.useRef(0) const divRef = React.useRef(null) renderRef.current++ const data = useControls({ color: { value: '#f00', onChange: (v) => { divRef.current!.style.color = v divRef.current!.innerText = `Transient color is ${v}` }, }, }) return (
A data (should be empty)
{JSON.stringify(data, null, '  ')}
A rendered {renderRef.current} time
) } function B() { const data = useControls({ color: { value: '#f00' }, }) return (
B data (should update)
{JSON.stringify(data, null, '  ')}
) } export const OnChange = () => { const [showA, setShowA] = React.useState(true) return ( <> {showA && } ) } OnChange.storyName = 'onChange' export const OnChangeWithRender = ({ transient }) => { const ref = React.useRef(null) const data = useControls({ color: { value: '#f00', onChange: (value) => { ref.current!.innerHTML = value }, transient, }, }) return (
color data (should{transient ? ' not' : null} update)
{JSON.stringify(data, null, '  ')}
Transient Value (should also update)

    
) } OnChangeWithRender.args = { transient: false, } OnChangeWithRender.storyName = 'onChange With Render' export const OnChangeFromPanel = () => { const ref = React.useRef(null) const [, set] = useControls(() => ({ value: { value: 0.1, optional: true, onChange: (value, path, context) => { const node = window.document.createElement('pre') node.innerText = JSON.stringify({ value, path, context }) ref.current!.appendChild(node) ref.current!.scrollTop = ref.current!.scrollHeight }, }, })) return ( <>
) } OnChangeFromPanel.storyName = 'onChange From Panel' export const EnforceInputType = () => { useControls({ color: { type: LevaInputs.STRING, value: '#f00', }, number: { type: LevaInputs.STRING, value: '1', }, }) return null } export const OnEditStartOnEditEnd = () => { const [isEditing, setIsEditing] = React.useState(0) const [editedInput, setEditedInput] = React.useState<{ value: any; path: string } | null>(null) const onEditStart = (value, path, context) => { setIsEditing((i) => i + 1) setEditedInput({ value, path }) } const onEditEnd = () => { setIsEditing((i) => i - 1) } const data = useControls({ string: { value: 'foobars', onEditStart, onEditEnd }, number: { value: 1, onEditStart, onEditEnd }, numberSlider: { value: 1, onEditStart, onEditEnd, min: 0, max: 10 }, interval: { value: [1, 10], min: 1, max: 10, onEditStart, onEditEnd }, vector2d: { value: [1, 1], onEditStart, onEditEnd }, vector3d: { value: [1, 1, 1], onEditStart, onEditEnd }, color: { value: '#fff', onEditStart, onEditEnd }, }) return (
Value
{JSON.stringify(data, null, '  ')}
        {isEditing === 0
          ? 'Not Editing'
          : `Editing ${editedInput!.path} with initial value ${String(editedInput!.value)}`}
      
) } OnEditStartOnEditEnd.storyName = 'onEditStart And onEditEnd' function OnEditComponent({ name }) { const [edited, setEdited] = React.useState(false) useControls({ input: { value: 'something', onEditStart: () => setEdited(true), onEditEnd: () => setEdited(false), }, }) return (
      Component {name} is being edited: {String(edited)}
    
) } export const OnEditStartOnEditEndMultiPanel = () => { const [toggled, toggle] = React.useState(true) return ( <> {toggled && } ) } OnEditStartOnEditEndMultiPanel.storyName = 'onEdit Multiple Callbacks' export const Ordered = () => { const values = useControls(() => ({ last: folder({ firstVal: 0 }, { order: 1, collapsed: true }), middle: folder({ secondVal: 0 }, { order: -1, collapsed: true }), first: { value: 'ola', order: -2 }, })) return (
{JSON.stringify(values, null, '  ')}
) } Ordered.storyName = 'ordered folders and inputs'