import { Listbox, Transition } from '@headlessui/react' import { CheckIcon, SelectorIcon } from '@heroicons/react/solid' import { useRender } from 'src/components/IdeWrapper/useRender' import { useIdeContext } from 'src/helpers/hooks/useIdeContext' import { Switch } from '@headlessui/react' import Svg from 'src/components/Svg/Svg' import { CadhubStringParam, CadhubBooleanParam, CadhubNumberParam, CadhubStringChoiceParam, CadhubNumberChoiceParam, } from './customizerConverter' const Customizer = () => { const [open, setOpen] = React.useState(false) const [shouldLiveUpdate, setShouldLiveUpdate] = React.useState(false) const { state, thunkDispatch } = useIdeContext() const customizerParams = state?.customizerParams const currentParameters = state?.currentParameters || {} const handleRender = useRender() const updateCustomizerParam = (paramName: string, paramValue: any) => { const payload = { ...currentParameters, [paramName]: paramValue, } thunkDispatch({ type: 'setCurrentCustomizerParams', payload }) shouldLiveUpdate && setTimeout(() => handleRender()) } if (!customizerParams?.length) return null return (
Parameters
{open && ( <>
Auto Update
{ if (newValue) handleRender() setShouldLiveUpdate(newValue) }} className={`${ shouldLiveUpdate ? 'bg-ch-purple-600' : 'bg-ch-gray-300' } relative inline-flex items-center h-6 rounded-full w-11 mr-6`} >
)}
{customizerParams.map((param, index) => { const otherProps = { value: currentParameters[param.name], onChange: (value) => updateCustomizerParam( param.name, param.type == 'number' ? Number(value) : value ), } if ( param.input === 'choice-string' || param.input === 'choice-number' ) { return } else if (param.input === 'default-string') { return } else if (param.input === 'default-number') { return } else if (param.input === 'default-boolean') { return } return
{JSON.stringify(param)}
})}
) } export default Customizer function CustomizerParamBase({ name, caption, children, }: { name: string caption: string children: React.ReactNode }) { return (
  • {name}
    {caption}
    {children}
  • ) } function BooleanParam({ param, value, onChange, }: { param: CadhubBooleanParam value: any onChange: (value: any) => void }) { return ( { onChange(newValue) }} className={`${ value ? 'bg-ch-gray-300' : 'bg-ch-gray-600' } relative inline-flex items-center h-6 rounded-full w-11 mr-6 border border-ch-gray-300`} > ) } function StringParam({ param, value, onChange, }: { param: CadhubStringParam value: any onChange: (value: any) => void }) { return ( onChange(target?.value)} /> ) } function ChoiceParam({ param, value, onChange, }: { param: CadhubStringChoiceParam | CadhubNumberChoiceParam value: any onChange: (value: any) => void }) { return (
    {value} {param.options.map((option, optionIdx) => ( `${ active ? 'text-ch-blue-600 bg-ch-gray-700' : 'text-ch-gray-300' } cursor-default select-none relative py-2 pl-10 pr-4` } value={option.value} > {({ selected, active }) => ( <> {option.name} {selected ? ( ) : null} )} ))}
    ) } function NumberParam({ param, value, onChange, }: { param: CadhubNumberParam value: any onChange: (value: any) => void }) { const [isFocused, isFocusedSetter] = React.useState(false) const [localValue, localValueSetter] = React.useState(value) const [isLocked, isLockedSetter] = React.useState(false) const [pixelsDragged, pixelsDraggedSetter] = React.useState(0) const step = param.step || 1 const commitChange = () => { let num = localValue if (typeof param.step === 'number') { num = Math.round(num / step) * step } if (typeof param.min === 'number') { num = Math.max(param.min, num) } if (typeof param.max === 'number') { num = Math.min(param.max, num) } num = Number(num.toFixed(2)) localValueSetter(num) onChange(num) } React.useEffect(() => { if (!isFocused) commitChange() }, [isFocused]) React.useEffect(() => localValueSetter(value), [value]) return (
    localValue) ? 'text-red-500' : '' }`} type="number" value={localValue} onFocus={() => isFocusedSetter(true)} onBlur={() => isFocusedSetter(false)} onKeyDown={({ key }) => key === 'Enter' && commitChange()} onChange={({ target }) => { const num = Number(target?.value) localValueSetter(num) }} max={param.max} min={param.min} step={step} />
    { isLockedSetter(true) target?.requestPointerLock?.() pixelsDraggedSetter(localValue) }} onMouseUp={() => { isLockedSetter(false) document?.exitPointerLock?.() commitChange() }} onMouseMove={({ movementX }) => { if (isLocked && movementX) { pixelsDraggedSetter(pixelsDragged + (movementX * step) / 8) // one step per 8 pixels localValueSetter(Number(pixelsDragged.toFixed(2))) } }} >
    ) }