Material UI - Stepper top and bottom labels with line - layout

I try to make a stepper with Material UI (V5).
Here is my code:
import * as React from 'react';
import Box from '#mui/material/Box';
import Stepper from '#mui/material/Stepper';
import Step from '#mui/material/Step';
import Typography from '#mui/material/Typography';
import StepLabel from '#mui/material/StepLabel';
const steps = [
'Step 1 - Top',
'Step 2 - Top',
'Ste^3 - Top',
];
export default function HorizontalLabelPositionBelowStepper() {
return (
<Box sx={{ width: '100%' }}>
<Stepper activeStep={1} alternativeLabel
>
{steps.map((label) => (
<Step key={label}>
<Typography>Top text</Typography>
<StepLabel>{label}</StepLabel>
</Step>
))}
</Stepper>
</Box>
);
}
That gives this result:
enter image description here
How to properly position the line and the 'top text' labels?
What about aligning the icons with the line such as: image with icon and line aligned
Do I need to create a separated Grid or Box before the Stepper to create the top labels? Thank you.
thank you for your suggestions.
Marc

Bellow I have the code you need including two solutions.
Solution 1 is faster and it will work better when the label-text of the steps have similar width between them. If not you have to specify the .MuiStepConnector-root left and right properties for each child if you want to have a better looking result.
Solution 2 includes a little more code and but will work no matter the width of each label-text. As it used a background color make sure to change it to match your background.
Here is the codesandbox to play with it and see both working solutions.
Please make sure to comment or uncomment the code depending the solution you want to try.
Code:
import * as React from "react";
import Box from "#mui/material/Box";
import Stepper from "#mui/material/Stepper";
import Step from "#mui/material/Step";
import StepLabel from "#mui/material/StepLabel";
import { Typography } from "#mui/material";
const steps = ["Step 1 - Top", "Step 2 - Top", "Ste^3 - Top"];
// Solution 1
const StepperSx = {
"& .MuiStepConnector-root": {
left: "calc(-50% + 40px)",
right: "calc(50% + 40px)"
},
"& .MuiStepConnector-line": {
marginTop: "22px"
}
};
// Solution 2
// const StepperSx2 = {
// textAlign: "center",
// "& .MuiStepConnector-root": {
// zIndex: "1",
// position: "relative"
// }
// };
// Solution 2
// const TypographySx = {
// zIndex: "2",
// background: "#FFF",
// display: "inline",
// position: "relative",
// padding: "0 15px"
// };
export default function HorizontalLabelPositionBelowStepper() {
return (
<Box sx={{ width: "100%" }}>
<Stepper
activeStep={1}
alternativeLabel
sx={StepperSx} // For solution 1
// sx={StepperSx2} // For solution 2
>
{steps.map((label) => (
<Step key={label}>
<Typography
align="center"
// sx={TypographySx} // For solution 2
>
Top text
</Typography>
<StepLabel>{label}</StepLabel>
</Step>
))}
</Stepper>
</Box>
);
}

Related

Empty Div Preventing Interaction with amCharts5 MapChart on Vue3

I decided to dip my toes in Vue and have had an idea for a website for a while which I'd like to use amCharts5 for.
I had some issues initially as all the info I could find was related to Vue2, but I think I've somewhat wrapped my head around Vue3 and its composition API.
The MapChart is created, however there is always a div slapped on top of it which prevent any interaction. If I delete this element via DevTools, the MapChart becomes interactive.
I've tried debugging this and commenting sections of the code out, regardless this div is always created. And I simply can't figure out if it's injected by Vue or if amCharts 5 is the culprit.
The highlighted element is the one I must delete for it to become interactive.
Here's how the component is setup;
<template>
<div class="testClass" ref="chartdiv">
</div>
</template>
<script setup lang="ts">
import * as am5 from "#amcharts/amcharts5";
import * as am5map from "#amcharts/amcharts5/map";
import am5geodata_worldLow from "#amcharts/amcharts5-geodata/worldLow";
import am5themes_Animated from '#amcharts/amcharts5/themes/Animated';
import { ref, onMounted, onUnmounted } from "vue";
const chartdiv = ref<HTMLElement | null>()
var root!: am5.Root;
onMounted(() => {
if (chartdiv.value) {
// Create the Root
var root = am5.Root.new(chartdiv.value);
// Setup the MapChart
var chart = root.container.children.push(
am5map.MapChart.new(root, {
panX: "rotateX",
panY: "rotateY",
projection: am5map.geoOrthographic(),
centerMapOnZoomOut: false
})
);
// Setup Animations
root.setThemes([
am5themes_Animated.new(root)
]);
// Create MapPolygons
var polygonSeries = chart.series.push(
am5map.MapPolygonSeries.new(root, {
geoJSON: am5geodata_worldLow
})
);
// Setup MapPolygon Styling
polygonSeries.mapPolygons.template.setAll({
tooltipText: "{name}",
fill: am5.color("#909090")
});
// Setup MapPolygon Hover Styling
polygonSeries.mapPolygons.template.states.create("hover", {
fill: am5.color("#FF0000"),
stroke: am5.color("#00FF00"),
strokeWidth: 2
});
polygonSeries.mapPolygons.template.events.on("click", function(event) {
//console.log("Clicked: {0}", event.target);
});
// Setup Background
var backgroundSeries = chart.series.unshift(
am5map.MapPolygonSeries.new(root, {})
);
backgroundSeries.mapPolygons.template.setAll({
fill: am5.color(0x2c84d0),
stroke: am5.color(0x2c84d0)
});
backgroundSeries.data.push({
geometry: am5map.getGeoRectangle(90, 180, -90, -180)
});
}
});
onUnmounted(() => {
if (root) {
root.dispose();
}
});
</script>
<style scoped>
.testClass {
width: 50vw;
height: 50vh;
}
</style>
When you create a Vite-powered Vue project, it automatically creates a bunch of CSS files for you. One of those is base.css.
Inside this file, you'll find these lines which causes all the headache;
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
position: relative;
font-weight: normal;
}
Removing those lines will fix the issue.

React Native Flatlist inside Wrapper Component break the scolling

Hello i have a Problem with my wrapper component. If i put inside the Flatlist component the scrolling doesn't work anymore. I try to pur everywhere flex:1 (on flatlist, on the wrapper itself) but no changes still broken.
What is my mistake?
I expected the normal scroll behavior.
import React from 'react';
import { KeyboardAvoidingView, TouchableWithoutFeedback, Keyboard, Platform } from 'react-native';
const KeyboardAvoidingViewWrapper = ({ children, keyboardOffset }) => {
const additionalOffset = Platform.OS === 'ios' ? 0 : 17;
return (
<KeyboardAvoidingView
keyboardVerticalOffset={keyboardOffset ? keyboardOffset + additionalOffset : 65 + additionalOffset}
behavior={Platform.OS == "ios" ? "padding" : "height"}
style={{ flex: 1, }}
>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
{children}
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
)
}
export default KeyboardAvoidingViewWrapper;
In the Screen:
<KeyboardAvoidingViewWrapper>
<View style={{ flex: 1 }}>
<FlatList
data={data}
.....
/>
</View>
</KeyboardAvoidingViewWrapper>
Any help is more than appreciate. Thank you.
try giving 'position' to behavior property to your KeyboardAvoidingView.
<KeyboardAvoidingView behavior='position'>

How to fetch coordinates of Polygon in React.JS using react-google-maps

I wants to fetch all the coordinates of a polygon drawn on Google's Map. And here is my code
import React from "react";
import { compose, withProps } from "recompose";
import {
withScriptjs,
withGoogleMap,
GoogleMap,
Marker
} from "react-google-maps";
//import withScriptjs from "react-google-maps/lib/async/withScriptjs";
import { DrawingManager } from "react-google-maps/lib/components/drawing/DrawingManager";
const MyMapComponent = compose(
withProps({
/**
* Note: create and replace your own key in the Google console.
* https://console.developers.google.com/apis/dashboard
* The key "AIzaSyBkNaAGLEVq0YLQMi-PYEMabFeREadYe1Q" can be ONLY used in this sandbox (no forked).
*/
googleMapURL:
"https://maps.googleapis.com/maps/api/js?key=AIzaSyALpmb4KhFoR2Kcvty21gzzegprl4ilIgs&v=3.exp&libraries=geometry,drawing,places",
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `400px` }} />,
mapElement: <div style={{ height: `100%` }} />
}),
withScriptjs,
withGoogleMap
)(props => (
<GoogleMap
defaultZoom={8}
defaultCenter={new window.google.maps.LatLng(-34.397, 150.644)}
>
<DrawingManager
defaultDrawingMode={
window.google.maps.drawing.OverlayType.ControlPosition
}
defaultOptions={{
drawingControl: true,
drawingControlOptions: {
position: window.google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
window.google.maps.drawing.OverlayType.CIRCLE,
window.google.maps.drawing.OverlayType.POLYGON,
window.google.maps.drawing.OverlayType.POLYLINE,
window.google.maps.drawing.OverlayType.RECTANGLE
]
},
circleOptions: {
fillColor: `#ffff00`,
fillOpacity: 1,
strokeWeight: 5,
clickable: false,
editable: true,
zIndex: 1
}
}}
/>
{props.isMarkerShown && (
<Marker position={{ lat: -34.397, lng: 150.644 }} />
)}
</GoogleMap>
));
My focus of work is to fetch all the coordinates of that polygon that should be drawn on Google Maps.I also wants to store these coordinates in MongoDB using mongoose and NodeJs as backend.
We can use this function to get all the coordinates of a polygon or any other reactangle.
function getPaths(polygon) {
var polygonBounds = polygon.getPath();
var bounds = [];
for (var i = 0; i < polygonBounds.length; i++) {
var point = {
lat: polygonBounds.getAt(i).lat(),
lng: polygonBounds.getAt(i).lng()
};
bounds.push(point);
}
console.log(bounds);
}
And in GoogleMap component, i simplified the above code by given way.
<DrawingManager
drawingMode={"polygon"}
onPolygonComplete={value => console.log(getPaths(value))} />

React native router flux : how to overrride burger button style?

Is there way to customize padding / position... of the burger button.
In the doc, i just can find the drawerImage parameter to override the burger image...
Saddly no option without forking. You can check the code here:
https://github.com/aksonov/react-native-router-flux/blob/master/src/NavBar.js. Padding and position is fixed.
Actually there's a parameter for it : leftButtonStyle
in my case I use react-native-vector-icons getImageSource for the burger icon
componentWillMount() {
Promise.all([Icon.getImageSource('bars', 16, 'black')])
.then((values) => {
this.setState({
menuIcon: values[0],
});
});
}
then you do something like this:
const menuIcon = {
uri: this.state.menuIcon.uri,
height: 20,
width: 20,
resizeMode: 'stretch',
color: 'white',
};
then in your tabs scene
<Scene
key="main"
type="replace"
initial
drawerImage={menuIcon}
tabs
style={{ backgroundColor: theme.navColor, justifyContent: 'center' }}
>

React native, children of ScrollView wont fill full height

So I have a horizontal scrollview at the top of the view. The ScrollView contains nodes that have a specified width. I then have a border on the bottom of the ScrollView, like you can see in this screen cap: http://i.imgur.com/pOV1JFP.png
As you can see the child nodes of the ScrollView at the top don't reach the border. However, if I change the ScrollView to a View with flexDirection: 'row', then the child nodes fill the height fine. I've tried changing a few properties on the scrollview, such as:
Setting padding:0 on contentContainerStyle
automaticallyAdjustContentInsets={false}
Changing the values of contentInsets directly
None of those seem to fix the issue.
The scrollview code & style:
var styles = StyleSheet.create({
nav: {
padding: 0,
marginTop: 30,
flex: 1,
borderBottomWidth: 1,
borderColor: '#000000'
}
});
<ScrollView
style={[{width: screen.width}, styles.nav]}
horizontal={true}
showsHorizontalScrollIndicator={true}
automaticallyAdjustContentInsets={false}>
{dayNavItems}
</ScrollView>
The child components (makes up dayNavItems)
const styles = StyleSheet.create({
container: {
paddingLeft: 15,
paddingRight: 15,
width: 50,
justifyContent: 'center'
},
odd: {
backgroundColor: '#ccc'
},
selected: {
backgroundColor: '#39b54a'
},
text: {
fontFamily: 'Optima'
}
});
class DayNavItem extends React.Component {
static propTypes = {
day: React.PropTypes.object.isRequired,
odd: React.PropTypes.bool,
selectDay: React.PropTypes.func.isRequired,
selected: React.PropTypes.bool
};
render() {
const d = new Date(this.props.day.created_at);
const viewStyles = [styles.container];
if (this.props.selected) {
viewStyles.push(styles.selected);
} else if (this.props.odd) {
viewStyles.push(styles.odd);
}
return (
<TouchableOpacity style={viewStyles} onPress={() => this.props.selectDay(this.props.day.uuid)}>
<View>
<Text style={styles.text}>{getMonth(d)}</Text>
<Text style={styles.text}>{d.getDate()}</Text>
</View>
</TouchableOpacity>
);
}
}
Adding contentContainerStyle={{flexGrow: 1}} will do the trick.
<ScrollView contentContainerStyle={{flexGrow: 1}}>
</ScrollView>
There is a property called contentContainerStyle for ScrollView. I just solved a similar issue where I set flex: 1 to the ScrollView's styles, ScrollView's contentContainerStyle, and the child View component.
The other answers are correct, but just to provide a clarifying example:
<ScrollView contentContainerStyle={{ flex: 1 }}>
{children}
</ScrollView>
Setting flex: 1 for ScrollView's contentContainerStyle property did the trick for me.
I always end up creating this component in all my projects:
import * as React from 'react'
import { ScrollView, ScrollViewProps, StyleSheet } from 'react-native'
export function FullHeightScrollView(
props: {
children: React.ReactNode
} & Omit<ScrollViewProps, 'contentContainerStyle'>
) {
return (
<ScrollView contentContainerStyle={styles.grow} {...props}>
{props.children}
</ScrollView>
)
}
const styles = StyleSheet.create({
grow: { flexGrow: 1 },
})
Use it in place of React Native's ScrollView.
If ScrollView is wrapped inside of a SafeAreaView, put flex: 1 on SafeAreaView, this did the trick for me after hours of debugging...
Parent:
Child (styles ScrollView I implemented has nothing to do with the current issue you reported):
I have made a simple package for those who just want, like me, a working out of the box ScrollView, without having to apply all the time the styles to make it work properly.
https://github.com/SrBrahma/pagescrollview
Usage:
import { PageScrollView } from 'pagescrollview';
<PageScrollView>
{/** Your contents */}
</PageScrollView>

Resources