import * as radixColors from '@radix-ui/colors'; import { DragHandleDots2Icon } from '@radix-ui/react-icons'; import { Box, Card, Flex, ScrollArea, Select, Text, TextField, } from '@radix-ui/themes'; import { produce } from 'immer'; import { capitalize, startCase, times } from 'lodash'; import { Dispatch, ReactNode, SetStateAction, useCallback, useRef, } from 'react'; import { EmbedConfig, EmbedConfigType, ExtractEmbedConfigType, RadixColor, RadixColorBase, RadixColorVariant, RadixColorVariantRaw, radixGrays, RadixRadius, RadixSize, RadixTextColor, } from '../app/tools/embed/types'; import { toColorVar, toRadiusVar } from '../app/tools/embed/utilities'; interface EmbedConfigInputsProps { config: EmbedConfig; state: ExtractEmbedConfigType; setState: Dispatch>>; } export function EmbedConfigInputs({ config, state, setState, }: EmbedConfigInputsProps) { const mutateState = useCallback( (recipe: (draft: ExtractEmbedConfigType) => void) => { setState(produce(recipe)); }, [], ); const wrapper = useRef(null); const handlePointerMove = useCallback((event: PointerEvent) => { event.preventDefault(); if (!wrapper.current) return; wrapper.current.style.top = `${parseFloat(wrapper.current.style.top) + event.movementY}px`; wrapper.current.style.right = `${parseFloat(wrapper.current.style.right) - event.movementX}px`; }, []); const handlePointerUp = useCallback((event: PointerEvent) => { window.removeEventListener('pointermove', handlePointerMove); window.removeEventListener('pointerup', handlePointerUp); }, []); return ( { window.addEventListener('pointermove', handlePointerMove); window.addEventListener('pointerup', handlePointerUp); }} > {Object.entries(config).map(([key, setting]) => { let control: ReactNode; switch (setting.type) { case EmbedConfigType.Number: { control = ( { mutateState((draft) => { draft[key] = ( event.target as HTMLInputElement ).valueAsNumber; }); }} > {setting.unit && ( px )} ); break; } case EmbedConfigType.String: { control = ( { mutateState((draft) => { draft[key] = (event.target as HTMLInputElement).value; }); }} /> ); break; } case EmbedConfigType.SizeNo0: case EmbedConfigType.Size: { control = ( { mutateState((draft) => { draft[key] = value as RadixSize; }); }} > {times(10, (index) => setting.type === EmbedConfigType.SizeNo0 && index === 0 ? null : ( {index} ), )} ); break; } case EmbedConfigType.Radius: { control = ( { mutateState((draft) => { draft[key] = value as RadixRadius; }); }} > {times(5, (index) => ( {index} ))} Full ); break; } case EmbedConfigType.Color: { control = ( <> { mutateState((draft) => { (draft[key] as RadixColor).base = value as RadixColorBase; }); }} > {Object.entries(radixColors) .filter( ([key]) => !key.endsWith('A') && !key.endsWith('P3') && !key.endsWith('Dark'), ) .map(([key]) => ( {' '} {capitalize(key)} ))} { mutateState((draft) => { (draft[key] as RadixColor).variant = value as RadixColorVariant; }); }} > {times(12, (index) => { const variant = `${index + 1}` as RadixColorVariantRaw; return ( <> {' '} {variant} {' '} {variant} translucent ); })} ); break; } case EmbedConfigType.TextColor: { control = ( { mutateState((draft) => { draft[key] = value as RadixTextColor; }); }} > {' '} White {' '} Gray {Object.entries(radixColors) .filter( ([key]) => !key.endsWith('A') && !key.endsWith('P3') && !key.endsWith('Dark') && !radixGrays.includes(key), ) .map(([key]) => ( {' '} {capitalize(key)} ))} ); break; } } return ( {capitalize(startCase(key))} {control && {control}} {!control && ( Immutable )} ); })} ); }