refactor: update material selection styles and improve layout in WallProperties; enhance hover effects

This commit is contained in:
Nalvazhuthi 2025-06-12 17:45:54 +05:30
parent 752ba96ba8
commit 2ad6d8244d
2 changed files with 70 additions and 55 deletions

View File

@ -13,23 +13,26 @@ type Material = {
textureName: string; textureName: string;
}; };
// Initial and default material // Default and initial materials
const initialMaterial: Material = {
texture: wallTexture1,
textureName: "Grunge Concrete Wall",
};
const defaultMaterial: Material = { const defaultMaterial: Material = {
texture: defaultTexture, texture: defaultTexture,
textureName: "Default Material", textureName: "Default Material",
}; };
const initialMaterial: Material = {
texture: wallTexture1,
textureName: "Grunge Concrete Wall",
};
const WallProperties = () => { const WallProperties = () => {
const { wallHeight, wallThickness, setWallHeight, setWallThickness } = useBuilderStore(); const { wallHeight, wallThickness, setWallHeight, setWallThickness } = useBuilderStore();
const [activeSide, setActiveSide] = useState<"side1" | "side2">("side1"); const [activeSide, setActiveSide] = useState<"side1" | "side2">("side1");
const [materials, setMaterials] = useState<Material[]>([initialMaterial]); const [materials, setMaterials] = useState<Material[]>([
defaultMaterial,
initialMaterial,
]);
const [selectedMaterials, setSelectedMaterials] = useState<{ const [selectedMaterials, setSelectedMaterials] = useState<{
side1: Material | null; side1: Material | null;
@ -39,11 +42,11 @@ const WallProperties = () => {
side2: null, side2: null,
}); });
// Select initial material for both sides on mount // Set default material initially for both sides
useEffect(() => { useEffect(() => {
setSelectedMaterials({ setSelectedMaterials({
side1: initialMaterial, side1: defaultMaterial,
side2: initialMaterial, side2: defaultMaterial,
}); });
}, []); }, []);
@ -71,21 +74,16 @@ const WallProperties = () => {
}; };
const handleRemoveMaterial = (index: number) => { const handleRemoveMaterial = (index: number) => {
const updatedMaterials = materials.filter((_, i) => i !== index); const removedTexture = materials[index].texture;
// Ensure there's always at least one material const updatedMaterials = materials.filter((_, i) => i !== index);
const newMaterials = const newMaterials = updatedMaterials.length === 0 ? [defaultMaterial] : updatedMaterials;
updatedMaterials.length === 0 ? [defaultMaterial] : updatedMaterials;
setMaterials(newMaterials); setMaterials(newMaterials);
// Deselect the material if it's the one removed
setSelectedMaterials((prev) => { setSelectedMaterials((prev) => {
const updated = { ...prev }; const updated = { ...prev };
["side1", "side2"].forEach((side) => { ["side1", "side2"].forEach((side) => {
if ( if (updated[side as "side1" | "side2"]?.texture === removedTexture) {
updated[side as "side1" | "side2"]?.texture ===
materials[index].texture
) {
updated[side as "side1" | "side2"] = defaultMaterial; updated[side as "side1" | "side2"] = defaultMaterial;
} }
}); });
@ -120,8 +118,7 @@ const WallProperties = () => {
<div className="material-preview"> <div className="material-preview">
<div className="sides-wrapper"> <div className="sides-wrapper">
<button <button
className={`side-wrapper ${activeSide === "side1" ? "active" : "" className={`side-wrapper ${activeSide === "side1" ? "active" : ""}`}
}`}
onClick={() => setActiveSide("side1")} onClick={() => setActiveSide("side1")}
> >
<div className="label">Side 1</div> <div className="label">Side 1</div>
@ -137,8 +134,7 @@ const WallProperties = () => {
</button> </button>
<button <button
className={`side-wrapper ${activeSide === "side2" ? "active" : "" className={`side-wrapper ${activeSide === "side2" ? "active" : ""}`}
}`}
onClick={() => setActiveSide("side2")} onClick={() => setActiveSide("side2")}
> >
<div className="label">Side 2</div> <div className="label">Side 2</div>
@ -170,33 +166,37 @@ const WallProperties = () => {
<div className="no-materials">No materials added yet.</div> <div className="no-materials">No materials added yet.</div>
) : ( ) : (
<div className="material-container"> <div className="material-container">
{materials.map((material, index) => ( {materials.map((material, index) => {
<button const isSelected = selectedMaterials[activeSide]?.texture === material.texture;
className="material-wrapper"
key={`${material.textureName}_${index}`} return (
onClick={() => handleSelectMaterial(material)}
>
<div className="material-property">
<div className="material-image">
<img
draggable={false}
src={material.texture}
alt={material.textureName}
/>
</div>
<div className="material-name">{material.textureName}</div>
</div>
<button <button
className="delete-material" className={`material-wrapper ${isSelected ? "selectedMaterial" : ""}`}
onClick={(e) => { key={`${material.textureName}_${index}`}
e.stopPropagation(); onClick={() => handleSelectMaterial(material)}
handleRemoveMaterial(index);
}}
> >
<RemoveIcon /> <div className="material-property">
<div className="material-image">
<img
draggable={false}
src={material.texture}
alt={material.textureName}
/>
</div>
<div className="material-name">{material.textureName}</div>
</div>
<button
className="delete-material"
onClick={(e) => {
e.stopPropagation();
handleRemoveMaterial(index);
}}
>
<RemoveIcon />
</button>
</button> </button>
</button> );
))} })}
</div> </div>
)} )}
</div> </div>

View File

@ -1394,16 +1394,20 @@
} }
&.selected { &.selected {
background: var(--background-color-accent); background: var(--highlight-accent-color);
color: var(--text-button-color);
.aisle-color {
// color: var(--text-button-color);
}
&:hover { &:hover {
background: var(--background-color-accent); // background: var(--background-color-accent);
} }
} }
&:hover { &:hover {
background: var(--background-color-secondary); background: var(--highlight-accent-color);
// background: var(--background-color-secondary);
} }
} }
} }
@ -1680,6 +1684,7 @@
padding: 0; padding: 0;
margin: 0; margin: 0;
max-height: 50vh; max-height: 50vh;
overflow: hidden;
.header-wrapper { .header-wrapper {
display: flex; display: flex;
@ -1737,7 +1742,6 @@
.preview { .preview {
width: 90%; width: 90%;
// width: 100%;
height: 111px; height: 111px;
img { img {
@ -1749,9 +1753,10 @@
} }
.materials { .materials {
padding: 6px 12px;
max-height: 250px; max-height: 250px;
overflow: auto; overflow: auto;
margin-bottom: 6px;
padding: 0 12px;
.material-container { .material-container {
display: flex; display: flex;
@ -1762,6 +1767,16 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 4px 6px;
border-radius: 12px;
&:hover {
background: var(--highlight-accent-color);
}
&.selectedMaterial {
background: var(--highlight-accent-color);
}
.material-property { .material-property {
display: flex; display: flex;
@ -1769,8 +1784,8 @@
gap: 6px; gap: 6px;
.material-image { .material-image {
width: 30px; width: 34px;
height: 30px; height: 34px;
border-radius: 6px; border-radius: 6px;
overflow: hidden; overflow: hidden;