How to make non-interactive Grid overlay? - css

I want to have the Grid visible on my site while i'm developing it, a-la Adobe XD style (link to image), to better understand how much place elements are taking(or should take).
The code underneath works but I have to manually specify Width of the grid when setting position to 'fixed' or 'absolute'.
There must be a more elegant way to do this.
Any suggestions on how to do this?
const testGridItems = () =>{
var list = new Array();
for(let i=0; i<12; i++){
list.push(
<Grid item xs={1}>
<div align='center'
style={{
height: '100vh',
position:'relative',
backgroundColor: '#F6BB42',
opacity:0.2}
}>
{i+1}
</div>
</Grid>
)
}
return list;
}
const testGrid = () => {
return (
<Grid container
style={{
width:1200,
position:'fixed'
}}
spacing={24} >
{ testGridItems() }
</Grid>
)
}

Related

Changing react-leaflet map width with button click

I am working on a map with react-leaflet. I placed a button on the map that will ideally open a menu on the left side of the map. The way I want to open up the menu is by changing the width of the map from 100% to 80%. The menu button toggles a boolean, which ideally the map will rerender and resize when the button clicks.
this is the code in my App.js
export default function App() {
const [isMarkerClick, setIsMarkerClick] = React.useState(false);
const [isMenuOn, setIsMenuOn] = React.useState(false);
function toggleMarker() {
setIsMarkerClick(prevClick => !prevClick);
}
function toggleMenu() {
setIsMenuOn(prevMenu => !prevMenu);
}
return (
<div>
<MainMap isMenuOn={isMenuOn} />
<MarkerButton isMarkerClick={isMarkerClick} toggleMarker={toggleMarker} />
<MenuButton toggleMenu={toggleMenu} />
</div>
)
}
this is where the Map Code lives
export default function MainMap(props) {
const isMenuOn = props.isMenuOn;
const isMarkerClick = props.isMarkerClick;
const zoom = 15;
const position = ['39.9526', '-75.1652'];
const [marker, setMarker] = React.useState(["", ""])
return (
<div>
<MapContainer
center={position}
zoom={zoom}
zoomControl={false}
style={{
height: "100vh",
width: isMenuOn ? "80vw" : "100vw"
}}
>
<TileLayer
attribution='© OpenStreetMap contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={marker}></Marker>
{isMarkerClick && <ClickTrack setMarker={setMarker} />}
</MapContainer>
</div>
)
}
as of now, when I click the menu button, the isMenuOn state updates and which then feeds back into the MapContainer and should rerender with a new width but it doesn't. Any Ideas on how to get change the map size with a click of button using react?
example of the menu button
I thought that when clicking the menu button and changing the state of isMenuOn to "true", the mapcontainer would be listening and rerender with using the new width. Although it seems like setting the width through style ={{}}, might not allow for changes?
React Leaflet will only set the width and height when the component mounts and does not update it with the state changes, in order to update the map's width you need to re-render the component fully and to do that set the component's key to something that will change with the isMenuOpen value
here is an example
<MapContainer
center={position}
zoom={zoom}
zoomControl={false}
key={isMenuOn ? "open-state": "closed-state"}
style={{
height: "100vh",
width: isMenuOn ? "80vw" : "100vw"
}}
>
The accepted answer works, but I suspect it would cause a full map reload. You can try keeping the width value static in the MapContainer element, and instead change it the wrapping div like this:
<div style={{ width: isMenuOn ? '80vw' : '100vw' }}>
<MapContainer
center={position}
zoom={zoom}
zoomControl={false}
style={{
height: '100vh',
width: '100%',
}}
/>
</div>
There is a caveat though; the map needs to be informed of the change in size, otherwise it will seem buggy. I suspect that's why the developers don't update the style after the map mount.
You can however add a map child that monitors the isMenuOn prop (or any other prop that changes your layout), and let the map instance know they should invalidate everything about sizing:
function LayoutListener({ isMenuOn }) {
const map = useMap();
useEffect(() => {
map?.invalidateSize();
}, [map, isMenuOn]);
return null;
}
And then just put in the MapContainer children:
<MapContainer>
<LayoutListener isMenuOn={isMenuOn} />
{otherChildren}
</MapContainer>

ReactJS App: Is it possible to order the rendering of specific divs?

I'm trying to create a ReactJS (using react bootstrap) mobile app that can resize (expand or contract) itself based on the screensize. The dimensions of one part of the app need to be calculated based on how much space is left on the screen after all other parts have rendered.
For example, consider the below markup -
var calcWidth = (100 / tableSize).toString() + '%';
return(
<Container>
<Row id='1'>Header and other static stuff here</Row>
<Row id='2'>
//A db driven table with square shaped cells goes here. It has the below structure -
<Container style={{width:'100%'}}>
<Row><Col style={{width:calcWidth, paddingBottom:calcWidth}}></Col>...</Row>
...
</Container>
</Row>
<Row id='3'>Footer and other static stuff here</Row>
</Container>
);
In the above markup, Row id 1 and 3 contain static stuff like headers, footers, buttons, titles etc. The Row id 2 contains a table that can contain "n" number of cells and each cell needs to be square shaped with content horizontally and vertically centerd.
The above code correctly calculates the width of each cell from the width of the container (which is 100%) and creates square shaped cells and fits perfectly horizontally. But since the height is same as the width, it gets bigger vertically and drives the footer beyond the screen. We want to avoid scrollbars. The solution seems to be to calculate calcWidth based on the remaining height available to the table, something like the below -
var remainingHeight = <total height of the container> - <height taken up by Row 1> - <height taken up by Row 3>
var width = <width of the screen>
var calcWidth = ((remainingHeight < width ? remainingHeight : width) / tableSize).toString() + '%';
My questions are -
How to calculate the remainingHeight variable above? How to let Row1 and Row3 render before Row2 and then calculate the remaining height?
How to find the total height and width of the container?
Any other better way of doing this? I'm just a newbie, probably there are some css tools to do it more efficiently?
Here you can find an example on how to calculate the height of react components after rendering:
export default function App() {
const [height1, setHeigt1] = useState(0);
const [height2, setHeight2] = useState(0);
const [height3, setHeight3] = useState(0);
const [remainingHeight, setRemainingHeight] = useState(0);
useEffect(() => {
const remainingHeight = 100 - height1 - height2 - height3;
console.log(remainingHeight);
setRemainingHeight(remainingHeight);
}, [setRemainingHeight, height1, height2, height3]);
return (
<div
id="container"
style={{
height: "100px",
backgroundColor: "firebrick",
padding: "15px"
}}
>
<ResizableComponent
id="component-1"
content={`Initial component 1 height = ${height1}`}
onHeightUpdated={setHeigt1}
/>
<ResizableComponent
id="component-2"
content={`Initial component 2 height = ${height2}`}
onHeightUpdated={setHeight2}
/>
<ResizableComponent
id="component-3"
content={`Initial component 3 height = ${height3}`}
onHeightUpdated={setHeight3}
remainingHeight={remainingHeight}
/>
</div>
);
}
export function ResizableComponent({
id,
content,
onHeightUpdated,
remainingHeight
}) {
const [height, setHeight] = useState(0);
const [isFirstRender, setIsFirstRender] = useState(true);
useEffect(() => {
const newHeight = document.getElementById(id).clientHeight;
if (height !== newHeight && isFirstRender) {
setHeight(newHeight);
setIsFirstRender(false);
}
}, [isFirstRender, id, height, onHeightUpdated, remainingHeight]);
useEffect(() => {
onHeightUpdated(height);
}, [height, onHeightUpdated]);
return (
<div
id={id}
style={
remainingHeight
? {
backgroundColor: "pink",
height: `calc(${height}px + ${remainingHeight}px)`
}
: { backgroundColor: "pink" }
}
>
{content}
</div>
);
}

Can Material-UI TextField width be set to match width of input text?

Is it possible to have Material-UI automatically adjust the width of the TextField element to match the width of the input text?
I am creating a form view/edit page and I'm rendering the data back into the same fields, however there is also a series of parameters which the server sets. It would be nice to render in disabled form elements and have their width automatically fit.
I've played with the width properly of both TextField and the underlying Input with no success. I could potentially count the characters and set a width in JS, but I'd rather a CSS solution.
<TextField
disabled={true}
label={"UUID"}
value={"7be093a5647d41ff8d958928b63d11f5"}
style={{width: "auto"}}
InputProps={{
style: {width: "100%"}
}}
/>
https://codesandbox.io/s/material-demo-forked-c3llv
You could base the width of the input on the length of the text
const FONT_SIZE = 9
const DEFAULT_INPUT_WIDTH = 200
const [textValue, setTextValue] = useState("")
const [inputWidth, setInputWidth] = useState(DEFAULT_INPUT_WIDTH)
useEffect(() => {
if (textValue.length * FONT_SIZE > DEFAULT_INPUT_WIDTH) {
setInputWidth((textValue.length + 1) * FONT_SIZE)
} else {
setInputWidth(DEFAULT_INPUT_WIDTH)
}
}, [textValue])
return (
<div>
<TextField
label={"UUID"}
value={textValue}
onChange={(e) => setTextValue(e.target.value)}
InputProps={{
style: { width: `${inputWidth}px` },
}}
/>
</div>
)
Below is the forked codesandbox
Reference: this answer

How can i scroll bottom on onPress of button in react-native?

I have added the button on simple screen and I want to scroll Bottom whenever I press the button. what code to add to button onPress?
render() {
return (
<ScrollView>
{this.yourComponents()}
<Button>Scroll To Bottom </Button>
</ScrollView>
)
}
You could do this using ref.
render() {
return (
<ScrollView ref={scrollView => this.scrollView = scrollView}>
{this.yourComponents()}
<Button onPress={() => {this.scrollView.scrollToEnd()}}>Scroll To Bottom </Button>
</ScrollView>
)
}
You can also do this using the useRef hook.
const scrollView = useRef();
const scrollView = useRef();
const onPress = () => {
scrollView.current.scrollToEnd();
}
<Button onPress={onPress} />
This question is quite similar to this one but isn't exactly the same, that is why i'll provide an answer.
ScrollView provide a ScrollTo() method that allows you to scroll to a x/y position in your scrollview.
let _scrollViewBottom
<ScrollView
ref='_scrollView'
onContentSizeChange={(contentWidth, contentHeight)=>{
_scrollViewBottom = contentHeight;
}}>
</ScrollView>
then use the ref name of the scroll view like
this.refs._scrollView.scrollTo(_scrollViewBottom);
Additionally, if your goal is to frequently push new data and scroll at the end of your scrollview, you might wanna take a look at react-native-invertible-scroll-view.
InvertibleScrollView is a React Native scroll view that can be inverted so that content is rendered starting from the bottom, and the user must scroll down to reveal more. This is a common design in chat applications
For functional component
<ScrollView
ref={ref => { scrollView = ref }}
onContentSizeChange={() => scrollView.scrollToEnd({ animated: true })}
>
...
</ScrollView>
For class component
<ScrollView
ref={ref => { this.scrollView = ref }}
onContentSizeCange={() => this.scrollView.scrollToEnd({ animated: true })}
>
...
</ScrollView>
let _scrollViewBottom
<ScrollView
ref={scrollViewRef}
onContentSizeChange={(contentWidth, contentHeight)=>{
_scrollViewBottom = contentHeight;
// this make move your scroll
scrollViewRef.current.scrollTo({x:0,y:_scrollViewBottom ,animated:true});
}}>
</ScrollView>
Additionally, if your goal is to frequently push new data and scroll at the end of your scrollview, you might wanna take a look at react-native-invertible-scroll-view.
InvertibleScrollView is a React Native scroll view that can be inverted so that content is rendered starting from the bottom, and the user must scroll down to reveal more. This is a common design in chat applications

React-native: How do I allow composite ListViews to spread out as long as their content requires?

I have a composite ListView, which is essentially a primary ListView with 3 sub-ListViews rendered as each "row" of the primary listview. The layout looks like this:
The code is something like this:
renderRow = (rowData, sectionID, rowID, highlightRow) => {
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
sectionHeaderHasChanged: (s1, s2) => s1 !== s2
});
console.log("rendering row"+rowData+"\n"+"sectionID"+sectionID+"rowID"+rowID);
nameList = this.eventsToNameListMap[sectionID];
return (
<ListView
enableEmptySections={true}
dataSource={ds.cloneWithRows(nameList[rowID])}
renderRow={this.renderInternalRow}
renderSectionHeader={ (sectionData,sectionID) => {
return <Text style = {styles.sectionHeader}>{rowID}</Text>
}
}
/>
);
}
renderInternalRow = (rowData, sectionID, rowID, highlightRow) => {
console.log("rendering internal row"+rowData+"\n"+"sectionID"+sectionID+"rowID"+rowID);
return (
<Text>{rowData}</Text>
);
}
render(){
return (
<View>
<ListView style = {styles.listView}
enableEmptySections={true}
dataSource={ this.state.dataSource}
renderRow={this.renderRow}
renderSectionHeader={this.renderSectionHeader}
/>
</View>
);
}
where the renderRow of the primary ListView renders another ListView as its row.
However, the problem is that each sub-ListView becomes evenly spaced out within each "row" of the primary ListView, causing each sub-ListView to become internally scrollable so that it can fit the fixed width. I want each sub-ListView to space out as much as they need according to the length of their content. How do I achieve this with styles? My current configuration has no styles applied.

Resources