'use client' import { getCatalogMaterialById, getLibraryMaterialIdFromRef, getMaterialsForCategory, MATERIAL_CATEGORIES, type MaterialSchema, type MaterialTarget, toLibraryMaterialRef, } from '@pascal-app/core' import { useEffect, useState } from 'react' import { triggerSFX } from '../../../lib/sfx-bus' import useEditor from '../../../store/use-editor' type MaterialPickerProps = { value?: MaterialSchema selectedMaterialPreset?: string onChange?: (material: MaterialSchema) => void onSelectMaterialPreset?: (materialPreset: string) => void disabled?: boolean nodeType?: MaterialTarget hideSideControl?: boolean } function getCategoryLabel(category: (typeof MATERIAL_CATEGORIES)[number]) { return category.charAt(0).toUpperCase() + category.slice(1) } export function MaterialPicker({ value, selectedMaterialPreset, onChange, onSelectMaterialPreset, disabled = false, }: MaterialPickerProps) { const setPaintPanelOpen = useEditor((state) => state.setPaintPanelOpen) const [showCustom, setShowCustom] = useState(!!value?.properties) const [selectedCategory, setSelectedCategory] = useState<(typeof MATERIAL_CATEGORIES)[number]>( MATERIAL_CATEGORIES[0], ) const availableCategories = MATERIAL_CATEGORIES.filter( (category) => getMaterialsForCategory(category).length > 0, ) const catalogItems = getMaterialsForCategory(selectedCategory) useEffect(() => { setShowCustom(!!value?.properties && !selectedMaterialPreset) }, [selectedMaterialPreset, value?.properties]) useEffect(() => { if (!selectedMaterialPreset && value?.properties) { setSelectedCategory('colors') return } const catalogId = getLibraryMaterialIdFromRef(selectedMaterialPreset) ?? value?.id ?? undefined const selectedCatalogEntry = getCatalogMaterialById(catalogId) if (selectedCatalogEntry?.category) { setSelectedCategory(selectedCatalogEntry.category) } }, [selectedMaterialPreset, value?.id]) const selectedCatalogId = selectedMaterialPreset ?? (value?.id ? toLibraryMaterialRef(value.id) : undefined) const selectedCatalogMaterialId = getLibraryMaterialIdFromRef(selectedCatalogId) ?? undefined const selectedCatalogEntry = getCatalogMaterialById(selectedCatalogMaterialId) const handleCatalogSelect = (materialId: string) => { if (disabled) return setShowCustom(false) setPaintPanelOpen(false) onSelectMaterialPreset?.(toLibraryMaterialRef(materialId)) } const handleCustomOpen = () => { if (disabled) return setShowCustom(true) setPaintPanelOpen(true) const forkColor = selectedMaterialPreset ? (selectedCatalogEntry?.previewColor ?? '#ffffff') : '#ffffff' onChange?.({ preset: 'custom', properties: { color: value?.properties?.color || forkColor, roughness: value?.properties?.roughness ?? 0.5, metalness: value?.properties?.metalness ?? 0, opacity: value?.properties?.opacity ?? 1, transparent: value?.properties?.transparent ?? false, side: value?.properties?.side ?? 'front', }, }) } return (
{(catalogItems.length > 0 || onChange) && (
{availableCategories.map((category) => ( ))}
{catalogItems.map((item) => { const isSelected = selectedCatalogId === toLibraryMaterialRef(item.id) return ( ) })} {selectedCategory === 'colors' && onChange ? ( ) : null}
)}
) }