javascript - para - diseño web adaptable
Reaccionar el diseño receptivo sin CSS (2)
Puede usar react-flexbox-grid para diseñar componentes fácilmente sin tocar ningún CSS.
const {Grid, Row, Col} = require(''react-flexbox-grid'');
const App = React.createClass({
render() {
return (
<Grid>
<Row>
<Col xs={6} md={3}>Hello, world!</Col>
</Row>
</Grid>
);
}
});
Me pregunto cuál es el mejor enfoque para implementar el diseño en la aplicación React.
Lo esencial
Digamos que queremos tener 4 componentes dispuestos en una grilla simple. La forma más básica sería algo como esto.
<svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
<A color="red" x={0} y={0} width={width/2} height={height/2} />
<B color="blue" x={width/2} y={0} width={width/2} height={height/2} />
<B color="green" x={0} y={height/2} width={width/2} height={height/2} />
<A color="yellow" x={width/2} y={height/2} width={width/2} height={height/2} />
</svg>
http://codepen.io/anon/pen/OWOXvV?editors=0010
Funcionará bien, pero escribir valores de tamaño explícitos es propenso a errores y no apto para desarrolladores. ¿Qué pasaría si pudiéramos usar valores porcentuales (0 - 1) en su lugar?
Contenedor simple
const Container = ({x, y, width, height, children}) => {
return (
<g transform={`translate(${x}, ${y})`}>
{React.Children.map(children, (child) => React.cloneElement(child, { // this creates a copy
x: child.props.x * width,
y: child.props.y * height,
width: child.props.width * width,
height: child.props.height * height
}))}
</g>
);
};
<svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
<Container width={width} height={height}>{/* one root container is given real pixel size */}
<Container width={1/2}>{/* it''s children recursively use 0-1 coordinates */}
<A color="red" height={1/2} />
<B color="green" y={1/2} height={1/2} />
</Container>
<Container x={1/2} width={1/2}>
<B color="blue" height={1/2} />
<A color="yellow" y={1/2} height={1/2} />
</Container>
</Container>
</svg>
http://codepen.io/anon/pen/PWEmVd?editors=0010
En este caso, permitiremos que el componente Contenedor trace sus valores relativos de niños a valores reales de píxeles. Es mucho más fácil de usar.
Contenedor de diseño
Otro paso sería crear un contenedor de diseño, fe HContainer que simplemente coloca a sus hijos horizontalmente.
const HContainer = ({ x, y, width, height, children }) => {
const c = React.Children.toArray(children);
const ratio = width / c.reduce((sum, child) => (sum + child.props.width), 0);
return (
<g transform={`translate(${x}, ${y})`}>
{c.reduce((result, child) => {
const width = child.props.width * ratio;
result.children.push(React.cloneElement(child, { // this creates a copy
x: result.x,
y: 0,
width,
height
}));
result.x += width;
return result;
}, { x: 0, children: [] }).children}
</g>
);
};
<svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
<HContainer width={width} height={height}>{/* one root container is given real pixel size */}
<Container width={1/4}>{/* it''s children recursively use 0-1 coordinates */}
<A color="red" height={1/2} />
<B color="green" y={1/2} height={1/2} />
</Container>
<VContainer width={3/4}>
<B color="blue" />
<A color="yellow" />
<HContainer height={1/2}>
<B color="pink" />
<A color="violet" width={3} />
<B color="#333" />
</HContainer>
</VContainer>
</HContainer>
</svg>
http://codepen.io/anon/pen/pRpwBe?editors=0010
Componentes receptivos
Digamos que nos gustaría eliminar algunos componentes cuando el ancho o la altura están por debajo de algún valor. Probablemente usarías un renderizado condicional como este.
const MinWidth = ({ children, width, minWidth, ... others }) => {
return minWidth > width ? null : <Container width={width} {... others }>{ children }</Container>;
};
<svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
<HContainer width={width} height={height}>{/* one root container is given real pixel size */}
<Container width={1/4}>{/* it''s children recursively use 0-1 coordinates */}
<A color="red" height={1/2} />
<B color="green" y={1/2} height={1/2} />
</Container>
<VContainer width={3/4}>
<B color="blue" />
<MinHeight height={1} minHeight={80}>
<A color="yellow" />
</MinHeight>
<HContainer height={1/2}>
<B color="pink" />
<A color="violet" width={3} />
<MinWidth width={1} minWidth={60}>
<B color="#333" />
</MinWidth>
</HContainer>
</VContainer>
</HContainer>
</svg>
http://codepen.io/anon/pen/dNJZGd?editors=0010
Pero esto deja espacios vacíos donde solían estar los componentes omitidos. Los contenedores de diseño deberían poder expandir los componentes renderizados para llenar el espacio disponible.
Disposición Responsive
Y esta es la parte difícil. No veo otra manera de ver si el componente se renderizará, sino de crear una instancia y representarlo (y sus hijos). Luego, si coloco 3 componentes secundarios dentro del espacio disponible y descubro que el 4to no debe representarse, tendré que volver a renderizar el anterior 3. Se siente como romper el flujo de Reacción.
¿Alguien tiene alguna idea?
Use flexbox en estilos en línea. Ya estás usando el estilo en línea desde el aspecto de tu código. Aquí hay algo de ayuda