Proper height of a child area of the draggable allotment pane - css

I have made a draggable split panel by https://github.com/johnwalley/allotment.
There is a main area (in yellow) and a console area; the console area has a title line (in blue) and the content area (in green). The splitting line between the main area (in yellow) and the title line (in blue) is draggable. The content area (in green) should be scrollable.
At the moment, I set height: "70%" for the content area. If I set height: "100%" (relative to its parent which is the second Allotment.Pane), it would exceed the screen.
However, I would like to set properly the height of the content area such that the content area always covers the rest of the page. In other words, the height of the content area will be the height of the viewport - the height of the main area (which is changeable) - the height of the console title line (which does not change).
Does anyone know how to amend the code to achieve that?
https://codesandbox.io/s/reset-forked-jb86xu?file=/src/App.js
import React from "react";
import { Allotment } from "allotment";
import "allotment/dist/style.css";
import styles from "./App.module.css";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
toExpand: true
};
this.myRef = React.createRef();
}
handleChange = (sizes) => {
if (sizes.length > 1) {
if (sizes[1] < 31) {
this.setState({ toExpand: true });
} else {
this.setState({ toExpand: false });
}
}
};
render() {
return (
<div>
<div className={styles.container}>
<Allotment vertical onChange={this.handleChange} ref={this.myRef}>
<Allotment.Pane>
<div style={{ backgroundColor: "yellow", height: "100%" }}>
Main Area
</div>
</Allotment.Pane>
<Allotment.Pane preferredSize="0%">
<div
onClick={() => {
if (this.state.toExpand) {
this.myRef.current.resize([50, 50]);
} else {
this.myRef.current.resize([10000, 0]);
}
}}
style={{ backgroundColor: "blue" }}
>
Console Title
{this.state.toExpand ? "ArrowUp" : "ArrowDown"}
</div>
<div
style={{
backgroundColor: "green",
height: "70%",
overflow: "scroll"
}}
>
Content1
<br />
Content2
<br />
Content3
<br />
Content4
<br />
Content5
<br />
</div>
</Allotment.Pane>
</Allotment>
</div>
</div>
);
}
}

Not sure if I fully understand the preferred result, but perhaps consider to wrap the 2 area boxes in the second panel in one flex container with height: 100%. This way, the green "content" area could be styled to take the remaining space with flex-grow instead of percentage.
Forked demo with modifications: codesandbox (it seems that the forked demo need to run in a new tab to avoid showing a page scrollbar).
<div className={styles.container}>
<Allotment vertical onChange={this.handleChange} ref={this.myRef}>
<Allotment.Pane>
<div style={{ backgroundColor: "yellow", height: "100%" }}>Main Area</div>
</Allotment.Pane>
<Allotment.Pane preferredSize="0%">
<section
style={{
height: "100%",
display: "flex",
flexDirection: "column",
}}
>
<div
onClick={() => {
if (this.state.toExpand) {
this.myRef.current.resize([50, 50]);
} else {
this.myRef.current.resize([10000, 0]);
}
}}
style={{ backgroundColor: "blue" }}
>
Console Title
{this.state.toExpand ? "ArrowUp" : "ArrowDown"}
</div>
<div
style={{
backgroundColor: "green",
flexGrow: "1",
overflow: "auto",
}}
>
Content1
<br />
Content2
<br />
Content3
<br />
Content4
<br />
Content5
<br />
</div>
</section>
</Allotment.Pane>
</Allotment>
</div>

Related

Flexbox make each element fill screen width

I have multiple AgGrid tables that should be displayed side-by-side, but each table should take up the width of the entire screen.
I accomplished this by setting width of the parent element to ${tables.length}00%, but is there a more elegant/pure .css way to accomplish this?
Codesandbox link: https://codesandbox.io/s/multi-grid-width-8jqurj
const App = () => {
const rowData = [
{ make: "Toyota", model: "Celica", price: 35000 },
{ make: "Ford", model: "Mondeo", price: 32000 },
{ make: "Porsche", model: "Boxter", price: 72000 }
];
const tables = [rowData, rowData];
return (
<div
className="ag-theme-alpine"
style={{
display: "flex",
width: `${tables.length}00%`
}}
>
{tables.map((data) => (
<div style={{ width: "100%", height: 400 }}>
<AgGridReact rowData={data}>
<AgGridColumn field="make" />
<AgGridColumn field="model" />
<AgGridColumn field="price" />
</AgGridReact>
</div>
))}
</div>
);
};
Updated Answer:
I've updated my snippet as follows
Add width "max-content" to the parent and width: 100vw to each child element
<div
className="ag-theme-alpine"
style={{
display: "flex",
width: "max-content"
}}
>
{tables.map((data) => (
<div style={{ width: "100vw", height: 400 }}>
<AgGridReact rowData={data}>
<AgGridColumn field="make" />
<AgGridColumn field="model" />
<AgGridColumn field="price" />
</AgGridReact>
</div>
))}
</div>
Updated Snippet: ttps://codesandbox.io/s/multi-grid-width-forked-rx7chu
ORIGINAL ANSWER: I tried you snippet with:
width: `${tables.length}00vw`
I made this change to ensure that I covered all the viewport/window width instead of 100% of the parent container
Heres a fork of your snippet https://codesandbox.io/s/multi-grid-width-forked-rx7chu

Display navbar ontop of react-window

I'm trying to display a navbar on top of react window list. I'm using react-window and react-virtualized-auto-sizer. The problem is that when I add the navbar outside the AutoSizer it creates another scroll bar. sandbox. How could I position the navbar ontop of the list without another scroll bar being created?
Code:
const Row = ({ index, style }) => (
<div style={style}>Row {index}</div>
);
const Homepage = () => (<>
<div style={{ width: "100%", height: "100vh", overFlow: "hidden"}}>
<Navbar /> // this causes a second scroll bar
<AutoSizer>
{({ width, height }) => (
<>
<List
height={height}
itemCount={1000}
itemSize={35}
width={width}
>
{Row}
</List>
</>
)}
</AutoSizer>
</div>
</>
);
Change your dom architecture so your header is outside the AutoSizer
For example:
const App = () => (
<div style={{ width: "100%", height: "100vh" }}>
<div style={{ height: "10vh", backgroundColor: "lightgrey" }}>
header here
</div>
<div style={{ height: "80vh" }}>
<AutoSizer>
{({ width, height }) => (
<>
<List height={height} itemCount={1000} itemSize={35} width={width}>
{Tester}
</List>
</>
)}
</AutoSizer>
</div>
<div style={{ height: "10vh", backgroundColor: "lightgrey" }}>
footer here
</div>
</div>
);
Demo
In you style.css file you could add
body {
overflow: hidden;
}
it s not the most elegant solution but I guess it works.

How to adjust modal height with inline CSS in React

Currently, the modal is too small to contain all email inputs when adding multiple users, overflowing the modal. Tried to apply CSS's height 100% property with no success. Here's some of the code:
const divEmail = {
content: {
position: "relative",
display: "block",
margin: "0 50px 0 30px",
background: "transparent"}
};
class PageAssistantSplitCourrielsCollaborateurs extends Component {
render() {
ayantDroits.push(
<div style={{ height: "100%" }}>
<div key={`champ--courriel__${elem}`}>
<Label style={divEmail} htmlFor={`champ--courriel__${elem}`}>
{_aD.name}
</Label>
<Translation>
{t => (
<Input
style={divEmail}
name={`champ--courriel__${elem}`}
id={_aD.rightHolderId}
defaultValue={_aD.email}
placeholder={t("flot.split.inscription.exemple")}
required={this.state.requis}
autoFocus={this.state.autoFocus}
type="email"
onChange={this.onChange}
/>
)}
</Translation>
</div>
</div>
);
});
return (
<div style={{ height: "100%" }}>
<Translation>
{t => (
<div>
{ayantDroits}
</div>
)}
</Translation>
</div>
);
}
}

how to get React chartjs to resize back down with window

I have this code, which, for some reason, will grow when I resize a window, but not shrink. I was wondering how to remedy this.
https://codesandbox.io/s/react-chartjs-2-example-1nur4
import React from "react";
import { render } from "react-dom";
import LineDemo from "./LineDemo";
const styles = {
fontFamily: "sans-serif",
textAlign: "center"
};
const App = () => (
<div style={styles}>
<table style={{ width: "100vw", borderCollapse: "collapse" }}>
<tbody>
{Array.from({ length: 4 }, el => "foo")
.concat(<LineDemo />)
.map(el => (
<td style={{ border: "solid" }}>{el}</td>
))}
</tbody>
</table>
</div>
);
render(<App />, document.getElementById("root"));
Have a detailed look at https://www.chartjs.org/docs/latest/configuration/responsive.html. The Important Note section mentions how responsiveness can be achieved. It states that
Chart.js uses its parent container to update the canvas render and display sizes. However, this method requires the container to be relatively positioned and dedicated to the chart canvas only. Responsiveness can then be achieved by setting relative values for the container size.
In your case, the parent container for the line chart is the <div> element. The render function of LineDemo component in LineDemo.js file then can be modified to look like:
render() {
return (
<div style={{ position: "relative", margin: "auto", width: "80vw" }}>
<h2>Line Example</h2>
<Line ref="chart" data={data} />
</div>
);
}
Here is a working example: https://codesandbox.io/s/react-chartjs-2-example-hzygw
What worked for me was to add chart container a width style:
<div style={{width: '99%'}}>
<Bar options={options} data={data} />
</div>
However if I set width 100% it won't work lol

Element won't center inside Modal

I'm currently using the React Bootstrap Modal. I'm trying to center an element within a modal with flexbox, but having a lot of trouble doing just that. Below is my code, and how it currently looks.
import { Modal } from 'react-bootstrap'
import React from 'react';
import { Button } from 'react-bootstrap';
import * as welcome from '../../styles/welcome'
class Welcome extends React.Component{
constructor(props){
super(props)
this.state = {
showModal: true
}
this.close=this.close.bind(this)
this.open=this.open.bind(this)
}
componentWillReceiveProps(nextProps){
debugger
if(nextProps.modal_content !== this.props.modal_content){
this.setState({ showModal: true });
}
}
close(){
this.setState({ showModal: false });
}
open() {
this.setState({ showModal: true });
}
render() {
return (
<div>
<Modal style={welcome.welcomeBody} show={this.state.showModal} onHide={this.close}>
<div style={{display: 'flex', justifyContent: 'center'}}>
<div style={{backgroundColor: 'black', border: '1px solid black', borderRadius: '100%', width: '50px', height: '50px'}}></div>
</div>
</Modal>
</div>
);
}
}
export default Welcome
You are applying flex in the image to align it center...which is wrong...
Flex always be applied to the parent container so that its children items use the flex features.
Wrap your image in a div and then apply display:flex and justify-content:center to that div so that image will be aligned centered.
<div style={{display: 'flex',justifyContent: 'center'}}>
<img src="pic.png"></img>
</div>
<div style="display: flex;justify-content: center;">
<img src="http://via.placeholder.com/350x150">
</div>
Updated Code
<div style="display: flex;justify-content: center;">
<div style="background-color:black;border:1px solid;height:50px;width:50px;border-radius:50%;"></div>
</div>

Resources