'use client' import { getCatalogMaterialById, getLibraryMaterialIdFromRef, getMaterialsForCategory, MATERIAL_CATEGORIES, type MaterialSchema, type MaterialTarget, toLibraryMaterialRef, } from '@pascal-app/core' import { useEffect, useRef, useState } from 'react' 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]) { if (category === 'roof') return 'Roofing' 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 categoryScrollRef = useRef(null) const catalogItems = selectedCategory === 'other' ? getMaterialsForCategory('other') : getMaterialsForCategory(selectedCategory) useEffect(() => { setShowCustom(!!value?.properties && !selectedMaterialPreset) }, [selectedMaterialPreset, value?.properties]) useEffect(() => { if (!selectedMaterialPreset && value?.properties) { setSelectedCategory('other') 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 handleCatalogSelect = (materialId: string) => { if (disabled) return setShowCustom(false) setPaintPanelOpen(false) onSelectMaterialPreset?.(toLibraryMaterialRef(materialId)) } useEffect(() => { const container = categoryScrollRef.current if (!container) return const handleWheel = (event: WheelEvent) => { const deltaX = event.deltaX const deltaY = event.deltaY const nextScrollLeft = container.scrollLeft + deltaX + deltaY if (nextScrollLeft === container.scrollLeft) return event.preventDefault() container.scrollLeft = nextScrollLeft } container.addEventListener('wheel', handleWheel, { passive: false }) return () => { container.removeEventListener('wheel', handleWheel) } }, []) const handleCustomOpen = () => { if (disabled) return setShowCustom(true) setPaintPanelOpen(true) onChange?.({ preset: 'custom', properties: { color: value?.properties?.color || '#ffffff', 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) && (
{MATERIAL_CATEGORIES.map((category) => ( ))}
{catalogItems.map((item) => ( ))} {selectedCategory === 'other' && onChange ? ( ) : null}
)}
) }