Elliptical Border Radius in React Native - css

I'm trying to recreate this shape in React Native. It's made with 2 overlapping shapes, one square and one with a border-radius on the top and bottom (the square is there to hide the border radius on the top).
Here's the CSS used to generate it:
#square {
width: 200px;
height: 180px;
background: red;
}
#tv {
position: relative;
margin-top: 100px;
width: 200px;
height: 200px;
margin: 20px 0;
background: red;
border-radius: 100px / 20px;
}
But I can't find any documentation on the border-radius property, so I don't know if it's possible to do elliptical radii like you can in CSS.

To construct an elliptical view
import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
//import { Constants } from 'expo';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.oval}/>
</View>
);
}
}
const styles = StyleSheet.create({
oval: {
width: 100,
height: 100,
borderRadius: 50,
//backgroundColor: 'red',
borderWidth:2,
borderColor:'black',
transform: [
{scaleX: 2}
]
},
container:{
flex:1,
alignItems:'center',
justifyContent:'center'
}
});
Playground: https://snack.expo.io/BJd-9_Fbb
This may be the shape similar to the one you have given.`
import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
//import { Constants } from 'expo';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.oval}/>
<View style={styles.square}/>
</View>
);
}
}
const styles = StyleSheet.create({
square:{
width:200,
height:180,
backgroundColor:'red',
position:'absolute',
top:160
},
oval: {
position:'absolute',
width: 100,
height: 200,
borderRadius: 50,
backgroundColor: 'red',
//borderWidth:2,
//borderColor:'black',
transform: [
{scaleX: 2}
]
},
container:{
flex:1,
alignItems:'center',
justifyContent:'center'
}
});
`
https://snack.expo.io/r11PnOK-Z``
EDIT
You can add different border-radius to different vertices like below
borderTopLeftRadius: '10%',
borderTopRightRadius: '30%',
borderBottomLeftRadius: '50%',
borderBottomRightRadius: '70%',
Playground: https://snack.expo.io/BJd-9_Fbb

Related

How to change the button color which consists of divs on press and back?

I have a react component which must be a custom button and contains from 2 divs and 1 . My goal here is to implement a function that changes the color from white to orange after onclick and becomes white again after I click somewhere else on the screen.
This is my first react project and I tried multiple approaches already and it still doesn´t work even if the code compiles.. Any suggestions here guys?
import React from 'react';
import { StyleSheet, TouchableOpacity } from 'react-native';
export default function PointMark() {
return (
<TouchableOpacity style={styles.touchPoint}>
<div style={styles.outerCircle}>
<div style={styles.innerCircle}></div>
</div>
</TouchableOpacity>
);
}
// Styles
const styles = StyleSheet.create({
touchPoint: {
width: 68,
height: 68,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 50,
border: "3px solid #ffffff",
},
outerCircle: {
width: 42,
height: 42,
borderRadius: 50,
border: "3px solid #ffffff",
position: 'relative',
},
innerCircle: {
width: 22,
height: 22,
borderRadius: 50,
backgroundColor: '#ffffff',
position: 'absolute',
top: 10,
left: 10,
}
});
How about using something like react-native-webhooks?
For your case, perhaps this:
import React from 'react';
import { StyleSheet, TouchableOpacity } from 'react-native';
import { useActive } from 'react-native-web-hooks';
export default function PointMark() {
const ref = React.useRef(null);
const isActive = useActive(ref);
return (
<TouchableOpacity
ref={ref}
style={{
...styles.touchPoint,
...(isActive && styles.touchPointActive)
}}>
<div style={styles.outerCircle}>
<div
style={{
...styles.innerCircle
...(isActive && styles.innerCircleActive)
}}
/>
</div>
</TouchableOpacity>
);
}
// Styles
const styles = StyleSheet.create({
touchPoint: {
width: 68,
height: 68,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 50,
border: "3px solid #ffffff",
},
touchPointActive: {
border: "3px solid #ff8000",
},
outerCircle: {
width: 42,
height: 42,
borderRadius: 50,
border: 'inherit',
position: 'relative',
},
innerCircle: {
width: 22,
height: 22,
borderRadius: 50,
backgroundColor: '#ffffff',
position: 'absolute',
top: 10,
left: 10,
},
innerCirlceActive: {
backgroundColor: '#ff8000',
}
});
A few things to note:
I set the border property on the outerCircle to inherit, that way you don't need to define the border again
div elements that are empty may be self-closing e.g. <div />
Here's the example they use on their NPM page:
import { useRef } from 'react';
import { StyleSheet, Linking, Text, Platform } from 'react-native';
import { useHover, useFocus, useActive } from 'react-native-web-hooks';
function Link({ children, href = '#' }) {
const ref = useRef(null);
const isHovered = useHover(ref);
const isFocused = useFocus(ref);
const isActive = useActive(ref);
return (
<Text
accessibilityRole="link"
href={href}
draggable={false}
onPress={() => Linking.openURL(href)}
tabIndex={0}
ref={ref}
style={[
styles.text,
isHovered && styles.hover,
isFocused && styles.focused,
isActive && styles.active,
]}>
{children}
</Text>
);
}
const styles = StyleSheet.create({
text: {
...Platform.select({
web: {
cursor: 'pointer',
outlineStyle: 'none',
borderBottomWidth: 1,
borderBottomColor: 'transparent',
transitionDuration: '200ms',
},
default: {},
}),
},
active: {
color: 'blue',
borderBottomColor: 'blue',
opacity: 1.0,
},
hover: {
opacity: 0.6,
},
focused: {
borderBottomColor: 'black',
},
});

Flexbox in React Native

I have a SafeAreaView and I am trying to apply some styles to it.
If I use inline styles, my text is centered on the screen.
const thisStyle = {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center'
}
<SafeAreaView style={thisStyle}>
...
</SafeAreaView>
However, if I define the styles in a scss file and import it in my component, the flexbox is not applied.
import styles from './login.scss';
...
<SafeAreaView style={styles.container}>
...
</SafeAreaView>
scss:
#import './src/base.scss';
.container {
display: flex;
width: 100%;
height: 100%;
background-color: $plump-purple;
align-items: 'center';
justify-content: 'center'
}
Note that the other properties work (the background changes color) the only thing that appears not working is the flexbox. Am I missing something?
Use it this way.
Main Class
import React, { Component } from 'react';
import { Text, StyleSheet, View } from 'react-native';
import styles from './styles';
export default class Example extends Component {
render() {
return <SafeAreaView style={styles.container}>...</SafeAreaView>;
}
}
Style Class
import { StyleSheet } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
width: '100%',
height: '100%',
backgroundColor: 'plump-purple',
alignItems: 'center',
justifyContent: 'center',
},
});

increase height of react native text input and text on input push on bottom?

this is my code:
const StyledTextInput = styled.TextInput`
background-color: red;
font-family: SF Pro Text Regular;
font-style: normal;
font-weight: normal;
font-size: 18px;
color: #000000;
align-items: flex-end;
justify-content: flex-end;
${(props) =>
props.error &&
`
border-bottom-color: red;
border-bottom-width: 1px;
`};
`;
basically what i am trying to do is increase height of text input but when it have text inside the text is in center, how do i make the text go on bottom?
Give a container to the TextInput and make that container act like the TextInput.
Also, use layout animation for a better experience.
Sample Code
import React, { Component } from 'react';
import {
View, Text, StyleSheet, TextInput, TouchableOpacity, LayoutAnimation, Platform, UIManager
} from 'react-native';
if (Platform.OS === 'android') {
if (UIManager.setLayoutAnimationEnabledExperimental) {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
}
export default class Calls extends Component {
state={ bigger: false }
focus=() => {
this.textInput.focus();
}
toggle=() => {
const { bigger } = this.state;
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
this.setState({ bigger: !bigger });
}
render() {
const { bigger } = this.state;
return (
<View style={styles.container}>
<TouchableOpacity
onPress={this.focus}
style={[styles.inputContainer, { height: bigger ? 200 : 60 }]}
activeOpacity={1}
>
<TextInput
ref={(e) => { this.textInput = e; }}
defaultValue="ASWIN"
style={styles.input}
/>
</TouchableOpacity>
<TouchableOpacity onPress={this.toggle}>
<Text style={styles.toggle}>Toggle</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
inputContainer: {
width: '90%', justifyContent: 'flex-end', borderWidth: 1,
},
input: {
fontSize: 20, height: 50, width: '100%', padding: 0, paddingHorizontal: 10,
},
toggle: {
fontSize: 20,
marginTop: 10,
backgroundColor: '#00000099',
paddingHorizontal: 10,
paddingVertical: 5,
color: '#fff',
},
});

How to make Material-UI Snackbar not take up the whole screen width using anchorOrigin?

I have a class in React which uses an input field which is part of the website header:
If the input is invalid then I want to display a snackbar. I'm using Material-UI components.
The problem is I defined anchorOrigin to be center and top as per Material-UI API. However the snackbar takes up the whole screen width while I want it to only take up the top center location of the screen. My message is quite short, for example "Value invalid" but if it's longer then I should be able to use newlines. I'm not sure if there's some setting in Material-UI API to alter this (I couldn't find one) or I need to use CSS.
This is my code:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import InputBase from '#material-ui/core/InputBase';
import Snackbar from '#material-ui/core/Snackbar';
import SnackbarMessage from './SnackbarMessage.js';
const classes = theme => ({
inputRoot: {
color: 'inherit',
width: '100%',
},
inputInput: {
paddingTop: theme.spacing.unit,
paddingRight: theme.spacing.unit,
paddingBottom: theme.spacing.unit,
paddingLeft: theme.spacing.unit * 10,
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('sm')]: {
width: 120,
'&:focus': {
width: 200,
},
},
}
});
class Test extends Component {
state = {
appId: '',
snackBarOpen: false
}
render() {
return (
<div>
<InputBase
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
value={'test'} />
<Snackbar
anchorOrigin={{
vertical: 'top',
horizontal: 'center'
}}
open={true}
autoHideDuration={5000}
>
<SnackbarMessage
variant="warning"
message={"test message"}
/>
</Snackbar>
</div>
)
}
}
Material-UI set Snackbars to full viewport-width below the breakpoint "md" (600px).
You can use overrides (https://material-ui.com/customization/overrides/) and set new values to the default CSS classes of the component described in the components API (i.e. https://material-ui.com/api/snackbar/). So you can override the class anchorOriginTopCenter as follows:
const styles = theme => ({
anchorOriginTopCenter: {
[theme.breakpoints.down('md')]: {
top: "your value/function here",
justifyContent: 'center',
},
},
root: {
[theme.breakpoints.down('md')]: {
borderRadius: 4,
minWidth: "your value / function here",
},
},
});
The first objects overrides the default class {anchorOriginTopCenter}, the second 'root' is applied to first element in your snackbar (probably a 'div').
I do not know if we can add some style to the component anchor origin field. I think the div needs to be managed using CSS. It's an anchor, not style.
<Snakbar
className = "my-snakbar"
{/*All your other stuff*/}
>
{//Stuff}
</Snakbar>
CSS
.my-snakbar {
width: 200px;
//Maybe use flexbox for positioning then
}
Let me know your thoughts
Daniel
Improved Answer
Code copied from origional question and modified
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Snackbar from '#material-ui/core/Snackbar';
const classes = theme => ({
inputRoot: {
color: 'inherit',
width: '100%',
},
inputInput: {
paddingTop: theme.spacing.unit,
paddingRight: theme.spacing.unit,
paddingBottom: theme.spacing.unit,
paddingLeft: theme.spacing.unit * 10,
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('sm')]: {
width: 120,
'&:focus': {
width: 200,
},
},
}
});
class ComingSoon extends Component {
render() {
const styles = {
container: {
position: "fixed",
top: "0px",
width: "100%",
height: "30px"
},
snakbar: {
background: "black",
color: "white",
width: "100px",
height: "100%",
display: "flex",
justifyContent: "center",
alignContent: "center",
margin: "0 auto"
}
};
return (
<div className = "snakbar-container" style = {styles.container}>
<Snackbar
className = "my-snakbar"
style = {styles.snakbar}
anchorOrigin={{
vertical: 'top',
horizontal: 'center'
}}
open={true}
autoHideDuration={5000}
>
<span>My Message</span>
</Snackbar>
</div>
)
}
}
export default ComingSoon;
Screen shot:
Let me know if this helped
Daniel

Can't align button to the bottom left of the screen - React Native

I would like to position my button to the bottom left of the screen. I have tried using bottom: 0 and left: 0, but that did not do anything. I researched a bit and discovered that I need to set the position: 'absolute'. However, when I do this, my button disappears completely.
How can I position by the button to the bottom left of the screen?
Here is my code:
import React, { Component } from 'react';
import { Button,Alert, TouchableOpacity,Image } from 'react-native'
import {
AppRegistry,
StyleSheet,
Text,
View,
} from 'react-native';
class Project extends Component {
render() {
return (
<View style={{backgroundColor: '#375D81', flex: 1}}>
<View style = {styles.container}>
<TouchableOpacity style = {styles.buttonText} onPress={() => { Alert.alert('You tapped the button!')}}>
<Text>
Button
</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
main: {
backgroundColor: 'blue'
},
container: {
alignItems: 'center',
},
buttonText: {
borderWidth: 1,
padding: 25,
borderColor: 'black',
backgroundColor: '#C4D7ED',
borderRadius: 15,
bottom: 0,
left: 0,
width: 100,
height: 100,
position: 'absolute'
}
});
AppRegistry.registerComponent('Project', () => Project);
You've forgotten to flex your container. Add: flex: 1 in there and you're all good:
container: {
alignItems: 'center',
flex: 1
},
You just need to set a width and height to your button then:
justifyContent: 'flex-end'
That's it
App.js
import React from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
import styles from './styles';
class Example extends React.Component {
render() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.button}>
<Text style={styles.text}>Button</Text>
</TouchableOpacity>
</View>
);
}
}
export default Example;
styles.js
export default {
container: {
flex: 1,
justifyContent: 'flex-end',
},
button: {
justifyContent: 'center',
textAlign: 'center',
width: 70,
height: 40,
backgroundColor: 'green',
borderRadius: 10,
margin: 20,
},
text: {
color: 'white',
textAlign: 'center',
margin: 10,
},
};
You will get something like this:
See Expo Snack: snack.expo.io/#abranhe/button-left
React-native elements are "rendered" from the top left when defining their position absolutely. This means when you are defining bottom: 0 and left: 0, this is rendering the item where you want horizontally, but vertically it will be off the screen. switch to
position 'absolute',
bottom: 100,
left: 0,
This should be what you are looking for

Resources