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 (
{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 (
)
}