Estoy tratando de crear una página con un diseño de libro, por lo que una página con algunas pestañas que se pueden expandir una a la vez.
Aquí un ejemplo de trabajo: https://codesandbox.io/s/book-layout-l28gh?file=/src/App.js:0-1419
import { useState } from "react"; const dataset = [ { name: "A section", description: "page A" }, { name: "B section", description: "page B" }, { name: "C section with long title", description: "page C" }, { name: "D section", description: "page D" } ]; export default function App() { return <Page />; } function Page({}) { const [openSection, setOpenSection] = useState(0); return ( <div style={{ display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }} > {dataset.map((datum, i) => { const { name } = datum; const isOpen = i === openSection; return ( <div key={name} style={{ height: "100%", backgroundColor: isOpen ? "white" : "lightgray", border: `1px solid ${isOpen ? "white" : "black"}`, padding: 10, flex: 1, flexGrow: isOpen ? 1 : 0, transition: "all 2s ease" }} > <div style={{ cursor: "pointer", writingMode: isOpen ? "horizontal-tb" : "vertical-rl", transition: "all 2s ease" }} onClick={() => setOpenSection(i)} > {name} </div> </div> ); })} </div> ); } <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>Si lo pruebas, puedes notar algunos problemas:
¿Por qué? ¿Cuál es el problema? ¿Hay un mejor enfoque para hacer un diseño como este?
Resolví todos tus problemas como dijiste.
Problema n. ° 1 -> resuelto: debe usar white-space:nowrap . si su texto es grande, al final de su cuadro se dividirá en la siguiente línea. white-space:nowrap , no permitas eso. (No lo recomiendo porque esto no es bueno para un texto de título demasiado largo).
Problema #2 -> resuelto: sucede cuando haces clic en algún elemento y en medio de la acción (cuadro de apertura) haces clic en otro. esto se debe a display: flex y flexGrow: 1 .
usó el cuadro flexible y justifyContent: "center" . así que cuando hace clic y hace clic en otro, su envoltorio se vuelve más pequeño y todas las tarjetas parecen estar más cerca unas de otras. flexGrow: 1 los romperá. entonces flexGrow: 5 es la solución.
Problema n. ° 3 -> resuelto: lugar incorrecto para configurar onClick . debe configurar el evento onClick en su cuadro, no en su texto. y una condición para el cursor es lo que quieres. (El elemento está seleccionado, por lo que el cursor debe ser default ; de lo contrario, debe ser un poiner ).
Bonificación :) si establece un ancho pequeño en su envoltorio para que su cuadro de rotación sea más bonito. gira al comienzo del texto y bingo.
import { useState } from "react"; const dataset = [ { name: "A section" }, { name: "B section" }, { name: "C section with long title" }, { name: "D section" }, { name: "E section" }, ]; function Page() { const [openSection, setOpenSection] = useState(1); return ( <div style={{ display: "flex", justifyContent: "center", alignItems: "center", height: "100vh", }} > {dataset.map((datum, i) => { const { name } = datum; const isOpen = i === openSection; return ( <div key={name} onClick={() => setOpenSection(i)} style={{ height: "100%", backgroundColor: isOpen ? "white" : "lightgray", border: `1px solid ${isOpen ? "white" : "black"}`, padding: "20px 30px", flex: 1, flexGrow: isOpen ? 5 : 0, transition: "all 1s linear", boxSizing: "border-box", cursor: openSection !== i ? 'pointer' : 'default', "&:first-child": { left: 0, }, "&:last-child": { right: 0, }, }} > <div style={{ transform: `rotate(${isOpen ? "0" : "90"}deg)`, transition: "all 1s linear", width: 1, whiteSpace: "nowrap", }} > {name} </div> </div> ); })} </div> ); } export default Page;white-space:nowrap ahora para que el texto no se encoja cuando se reduzca el tamaño. Haga que la posición de title div sea absoluta para que su ancho no interfiera con el diseño y la transición. import { useState } from "react"; const dataset = [ { name: "A section" }, { name: "B section" }, { name: "C section with long title" }, { name: "D section" }, { name: "E section" } ]; export default function App() { return <Page />; } function Page({}) { const [openSection, setOpenSection] = useState(0); return ( <div style={{ display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }} > {dataset.map((datum, i) => { const { name } = datum; const isOpen = i === openSection; return ( <div key={name} style={{ height: "100%", backgroundColor: isOpen ? "white" : "lightgray", border: `1px solid ${isOpen ? "white" : "black"}`, flex: 1, flexGrow: isOpen ? 1 : 0, transition: "all 2s ease", //my changes padding: 0, flexBasis: "1.2rem", cursor: !isOpen ? "pointer" : "auto", position: "relative" }} onClick={!isOpen ? () => setOpenSection(i) : null} > <div style={{ transition: "all 2s ease", //my changes transform: `rotate(${isOpen ? "0" : "90"}deg) translateX(${isOpen ? "0" : "50"}%)`, whiteSpace: "nowrap", width: isOpen ? "100%" : "1rem", position: "absolute", top: isOpen ? "1rem" : "0", left: isOpen ? "1rem" : "0", fontWeight: "bold" }} > {name} </div> </div> ); })} </div> ); }Seguiré el mismo orden en que presentaste tus problemas.