refactor: update material selection styles and improve layout in WallProperties; enhance hover effects
This commit is contained in:
parent
752ba96ba8
commit
2ad6d8244d
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue