When I have an absolute scrollview inside of a view, where the view is position relative and the scrollview is absolute, the contents of the absolute scrollview are hidden outside of the view, this occurs even if I have the parent view set as oveflow: "hidden"
I am trying it create a auto suggest drop down for a text input.
I have seen that this is an issue on android, but I am testing this on IOS and I am having the same issues.
From what I understood what I am doing should work as shown in this JSFiddle (https://jsfiddle.net/qax6dvrc/14/)
But it looks like this:
Styling
const styles = {
destinationInputContainer: {
width: '90%',
height: 50,
backgroundColor: '#fff',
borderRadius: 10,
marginBottom: '2.5%',
marginHorizontal: '5%',
// IOS
shadowColor: '#000',
shadowOffset: { width: 1, height: 4},
shadowOpacity: 0.5,
shadowRadius: 1,
elevation: 3,
position: "relative",
flexDirection: "row",
},
destinationInput: {
paddingLeft: 10,
paddingTop: 0,
flex: 1,
},
searchResults: {
position: "absolute",
top: 50,
zIndex: 1,
elevation: 5,
},
topContainer: {
position: "relative",
overflow: "visible"
}
}
Component Structure ( I have tried to remove all irrelevant code)
const DestinationInput = ({ _currentTextValue, _latLong, dragCallback, id, updateCallback}: destinationInputProps) => {
const updateValue = (newValue: string) => {
setCurrentText(newValue); // update the value stored in the state
updateCallback(inputId, newValue);
}
return (
<View style={styles.topContainer as any}>
<View style={styles.destinationInputContainer as any} >
<TextInput style={styles.destinationInput} value={currentText} placeholderTextColor='#000' placeholder='Destinations' onChangeText={(currentInput) => updateValue(currentInput)} />
<TouchableOpacity onLongPress={dragCallback} style={{flexDirection: "column", justifyContent: "center", flex: 1}}>
<Text>Drag</Text>
</TouchableOpacity>
</View>
<ScrollView style={styles.searchResults as any} >
<Text>Option1</Text>
<Text>Option2</Text>
<Text>Option3</Text>
</ScrollView>
</View>
);
};
export class DestinationSearch extends React.Component {
state: {currentDestinations: destinationInputProps[]} // specify the type for the props
constructor(props: any) {
super(props);
}
renderItem({ item, index, drag, isActive }: RenderItemParams<destinationInputProps>) {
return <DestinationInput updateCallback={this.updateSingleValue} _currentTextValue={item._currentTextValue} id={item.id} dragCallback={drag} />
}
render() {
return (
<View>
<ScrollView style={{maxHeight: 220}}>
<DraggableFlatList
data = { this.state.currentDestinations }
keyExtractor={(item, index) => `draggable-item-${item.id}`}
renderItem = {this.renderItem}
onDragEnd={({ data }) => { console.log(this.state.currentDestinations); this.setCurrentDestinations(data)}}
extraData = { this.state.currentDestinations }
/>
</ScrollView>
<Button title={"Add"} disabled={this.state.currentDestinations.length >= 5} onPress={this.addDestination}></Button>
</View>
);
}
}
Related
Context: I'm trying to add a parallax effect to the homepage of my website, but my parallax component AdvanceBanner is returning a height of 0 even though the children div is being rendered.
Whenever I try to render this component on a blank react project, everything works as intended but when I move it over to my main nextjs project it doesn't display as intended.
This tells me that it's either something with the parent components or it's the styling of the site.
Here's everything that's relevant, any sort of help/advice is very much appreciated :)
AdvancedBanner.tsx
import { ParallaxBanner } from "react-scroll-parallax";
import { BannerLayer } from "react-scroll-parallax/dist/components/ParallaxBanner/types";
export const AdvancedBannerTop = () => {
const background: BannerLayer = {
image:
"https://i.postimg.cc/662d6ZT1/Galaxy.png",
translateY: [0, 50],
opacity: [1, 0.3],
scale: [1.05, 1, "easeOutCubic"],
shouldAlwaysCompleteAnimation: true
};
const headline: BannerLayer = {
translateY: [0, 30],
scale: [1, 1.05, "easeOutCubic"],
shouldAlwaysCompleteAnimation: true,
expanded: false,
children: (
<div className="inset center">
<h1 className="headline white">Gaming Galaxy</h1>
</div>
)
};
const foreground: BannerLayer = {
image:
"https://s3-us-west-2.amazonaws.com/s.cdpn.io/105988/banner-foreground.png",
translateY: [0, 15],
scale: [1, 1.1, "easeOutCubic"],
shouldAlwaysCompleteAnimation: true
};
const gradientOverlay: BannerLayer = {
opacity: [0, 1, "easeOutCubic"],
shouldAlwaysCompleteAnimation: true,
expanded: false,
children: <div className="gradient inset" />
};
return (
<ParallaxBanner
layers={[background, headline, foreground, gradientOverlay]}
className="full"
/>
);
};
ParallaxApp.tsx
import { ParallaxProvider } from "react-scroll-parallax";
import { AdvancedBannerTop } from "./AdvancedBanner";
import './styles.module.css'
export default function ParallaxApp() {
return (
<ParallaxProvider>
<AdvancedBannerTop/>
<div className="center full background">
<h1 className="headline text-cloudy-day font-oxanium-bold">TEXT TWO</h1>
</div>
</ParallaxProvider>
);
}
styles.module.css
.subline {
font-family: "Oxanium", Helvetica, Arial, sans-serif;
font-weight: 250;
font-size: 1vw;
}
.headline {
font-family: "Oxanium", Helvetica, Arial, sans-serif;
font-weight: 600;
font-size: 10vw;
}
.inset {
position: absolute;
inset: 0;
}
.white {
color: white;
}
.gray {
color: #ffffff;
}
.full {
height: 100vh;
}
.center {
display: flex;
align-items: center;
justify-content: center;
}
.gradient {
background: linear-gradient(rgba(193, 28, 133, 0.5) 50%, #1F1329);
}
.background {
background-image: url('./area_bg01.jpg');
}
Layout.tsx
<main className="bkg1 py-6 md:py-12">
<div>{children}</div>
</main>
Index.tsx (homepage)
import ParallaxApp from "../components/Parallax Space/ParallaxApp"
function Home() {
return (
<div>
<ParallaxApp/>
</div>
);
}
export default Home;
Only "TEXT TWO" is currently being displayed on the homepage, but upon further inspection, all 4 BannerLayers are rendered just not displayed due to the height of ParallaxApp being 0.
I'm attempting to create a react component that will display 3 cards, each containing some information from an array horizontally. There would be left/right buttons allowing the user to scroll back and forth horizontally to 3 more cards until the array is completed.
I've been doing some research and have had a really difficult time finding a solution to complete this task easily. This is my first time using Material-UI so this is all quite new.
What can I do to obtain what I'm looking for? Is there some sort of scroll feature I can give to material-UI to easily create these left/right scroll buttons?
Thanks!
example:
Maybe you can try using a library like this one:
react-material-ui-carousel
Instead of putting images in this component, try putting cards instead.
Do you need the buttons, or just the horizontal scroll? This is a simple example of horizontal scroll section with images:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import GridList from '#material-ui/core/GridList';
import GridListTile from '#material-ui/core/GridListTile';
import GridListTileBar from '#material-ui/core/GridListTileBar';
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around',
overflow: 'hidden',
},
gridList: {
flexWrap: 'nowrap'
}
}));
const tileData = [
{
img: 'images/image1.jpg',
title: 'title'
},
{
img: 'images/image2.jpg',
title: 'title'
},
{
img: 'images/image3.jpg',
title: 'title'
}
];
export default function SingleLineGridList() {
const classes = useStyles();
return (
<div className={classes.root}>
<GridList className={classes.gridList} cols={2.5}>
{tileData.map((tile) => (
<GridListTile key={tile.img}>
<img src={tile.img} alt={tile.title} />
<GridListTileBar
title={tile.title}
/>
</GridListTile>
))}
</GridList>
</div>
);
}
I think for the buttons you would need to set a <div> for each section of 3, and set the href=#id on each button.
You can use below code to get it done. I have used some CSS properties to make it work. This will remove the additional usage of arrows to scroll horizontally.
I have used this in a Netflix clone app. This is a Row Component. I have used it in my Home page and passed different genre of movie list to it. Based on the genre it will show different movies in a row.
<div className="row">
{/* title */}
<h2>{title}</h2>
{/* container -> posters */}
<div className="row__posters">
{/* several row posters */}
{movies.map((movie) => (
<img
key={movie.id}
className="row__poster row__posterLarge"
src={`${image_base_url}${
isLargeRow ? movie.poster_path : movie.backdrop_path
}`}
alt={movie.name}
/>
))}
</div>
</div>
Below is the CSS used for above component.
.row {
margin-left: 20px;
color: white;
}
.row__posters {
display: flex;
overflow-x: scroll;
overflow-y: hidden;
padding: 20px;
}
.row__posters::-webkit-scrollbar {
display: none;
}
.row__poster {
width: 100%;
object-fit: contain;
max-height: 100px;
margin-right: 10px;
transition: transform 450ms;
}
.row__posterLarge {
max-height: 250px;
}
.row__posterLarge:hover {
transform: scale(1.09);
}
.row__poster:hover {
transform: scale(1.08);
}
I can't share the full code because it's mixed a lot with other code that is not related to this question, but here is something similar that I can share:
import React, { useState } from "react";
import { makeStyles } from "#material-ui/core/styles";
import Chip from "#material-ui/core/Chip";
import Box from "#material-ui/core/Box";
import Tabs from "#material-ui/core/Tabs";
import IconButton from "#material-ui/core/IconButton";
import styled from "#emotion/styled";
import ChevronLeftIcon from "#material-ui/icons/ChevronLeftRounded";
import ChevronRightIcon from "#material-ui/icons/ChevronRightRounded";
const StyledChip = styled(Chip)`
border-radius: 16px;
text-transform: capitalize;
color: ${(props) => (props.selected ? "#FFFFFF" : "#6877AE")};
background-color: ${(props) => (props.selected ? "#03194F" : "#FFFFFF")};
border: 4px solid ${"#03194F"};
border-color: ${(props) =>
props.selected ? "#03194F" : "rgba(0, 83, 229, 0.12)"};
.MuiChip-root&:hover {
background-color: ${(props) => (props.selected ? "#03194F" : "")};
}
`;
const StyledIconButton = styled(IconButton)`
left: ${(props) => (props.isLeft ? "0" : "none")};
right: ${(props) => (props.isLeft ? "none" : "0")};
height: 32px;
width: 32px;
position: absolute;
border-radius: 16px;
border: 1px solid gray;
//top: 33%;
background-color: white;
color: rgba(0, 83, 229, 1);
border-color: rgba(0, 83, 229, 0.12);
z-index: 1;
opacity: 1;
margin: 20px;
:hover {
box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2),
0px 4px 5px rgba(0, 0, 0, 0.14), 0px 1px 10px rgba(0, 0, 0, 0.12);
border-color: white;
background-color: inherit;
}
`;
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
justifyContent: "center",
flexWrap: "nowrap",
listStyle: "none",
padding: theme.spacing(0.5),
margin: 0,
overflow: "auto",
maxWidth: "100%"
},
chip: {
margin: theme.spacing(2)
}
}));
export default function ChipsArray() {
const classes = useStyles();
const [chipData, setChipData] = React.useState([
{ key: 0, label: "Angular" },
{ key: 1, label: "jQuery" },
{ key: 2, label: "Polymer" },
{ key: 3, label: "React" },
{ key: 4, label: "Vue" },
{ key: 5, label: "Knockout" },
{ key: 6, label: "Ember" },
{ key: 7, label: "D3" },
{ key: 8, label: "Google Charts" },
{ key: 9, label: "C+" },
{ key: 10, label: "C++" },
{ key: 11, label: "NodeJS" }
]);
const [selectedIndustryFilter, setSelectedIndustryFilter] = React.useState(
"Angular"
);
return (
<Box className={classes.root}>
<Tabs
variant="scrollable"
scrollButtons="on"
aria-label="scrollable auto tabs example"
ScrollButtonComponent={(props) => {
if (props.direction === "left") {
return (
<StyledIconButton isLeft {...props}>
<ChevronLeftIcon />
</StyledIconButton>
);
} else if (props.direction === "right") {
return (
<StyledIconButton {...props}>
<ChevronRightIcon />
</StyledIconButton>
);
} else {
return null;
}
}}
>
{chipData.map((data) => {
return (
<StyledChip
label={data.label}
onClick={() => {
setSelectedIndustryFilter(data.label);
console.log(data.label);
}}
selected={data.label === selectedIndustryFilter}
key={data.key}
className={classes.chip}
/>
);
})}
</Tabs>
</Box>
);
}
also check it here:
https://codesandbox.io/s/demo-material-ui-chips-single-line-with-scroll-forked-2f0z30?file=/src/App.js
I am trying to use React Navigation from inside another component which is primarily getting called from a screen.
Hierarchy: The login screen has a button component that has a TouchableOpacity component designed and that login button is supposed to call another screen, Home.
login.js
import React, { Component } from "react";
import { StyleSheet, View, Text, Button } from "react-native";
import { withNavigation } from 'react-navigation';
import CupertinoButtonSuccess from "../components/CupertinoButtonSuccess";
import CupertinoButtonWarning1 from "../components/CupertinoButtonWarning1";
import MaterialIconTextbox from "../components/MaterialIconTextbox";
//function Login(props) {
export default class Login extends Component {
static navigationOptions = {
headerShown: false
};
render() {
return (
<View style={styles.container}>
<Text style={styles.coMproTech1}>COMproTECH</Text>
<View style={styles.rectStack}>
<View style={styles.rect}>
<CupertinoButtonSuccess
Navigation={this.props.navigation}
text1="Login"
style={styles.cupertinoButtonSuccess}
></CupertinoButtonSuccess>
<CupertinoButtonWarning1
text1="Forgot Password"
style={styles.cupertinoButtonWarning1}
></CupertinoButtonWarning1>
<Button title='test' onPress={this.handleClick}></Button>
</View>
<View style={styles.rect2}></View>
<MaterialIconTextbox
textInput1="Enter email"
icon1Name="account"
style={styles.materialIconTextbox}
></MaterialIconTextbox>
<MaterialIconTextbox
icon1Name="account-key"
textInput1="Password"
style={styles.materialIconTextbox2}
></MaterialIconTextbox>
</View>
<Text style={styles.services1}>Services</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "rgba(74,144,226,1)"
},
coMproTech1: {
color: "rgba(247,242,242,1)",
fontSize: 36,
fontFamily: "Cochin-BoldItalic",
marginTop: 110,
marginLeft: 16
},
rect: {
top: 19,
left: 0,
width: 342,
height: 319,
backgroundColor: "rgba(255,255,255,1)",
position: "absolute",
borderRadius: 20,
borderBottomRightRadius: 20
},
cupertinoButtonSuccess: {
width: 65,
height: 39,
borderRadius: 6,
marginTop: 200,
marginLeft: 261
},
cupertinoButtonWarning1: {
width: 167,
height: 44,
borderRadius: 10,
marginTop: 9,
marginLeft: 159
},
rect2: {
top: 0,
left: 48,
width: 42,
height: 42,
backgroundColor: "rgba(255,255,255,1)",
position: "absolute",
transform: [
{
rotate: "45.00deg"
}
],
borderRadius: 7
},
materialIconTextbox: {
top: 59,
left: 0,
width: 343,
height: 48,
position: "absolute"
},
materialIconTextbox2: {
top: 141,
left: 0,
width: 343,
height: 48,
position: "absolute"
},
rectStack: {
width: 343,
height: 338,
marginTop: 125,
marginLeft: 16
},
services1: {
color: "rgba(247,242,242,1)",
fontSize: 36,
fontFamily: "Cochin-BoldItalic",
marginTop: -450,
marginLeft: 18
}
});
//export default Login;
CupertinoSuccess.js
import React, { Component } from "react";
import { StyleSheet, TouchableOpacity, Text, Button } from "react-native";
import { withNavigation } from 'react-navigation';
import { NavigationInjectedProps } from 'react-navigation';
import { createStackNavigator } from "react-navigation-stack";
function CupertinoButtonSuccess(props) {
return (
<TouchableOpacity
onPress={() => this.props.navigation.goBack()}
style={[styles.container, props.style]}>
<Text style={styles.caption}>{props.text1 || "Button"}</Text>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#4CD964",
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
paddingRight: 12,
paddingLeft: 12,
borderRadius: 5
},
caption: {
color: "#fff",
fontSize: 17,
//fontFamily: "Cochin-BoldItalic"
}
});
export default CupertinoButtonSuccess;
Getting error/exception:
undefined object 'this.props'
TypeError: undefined is not an object (evaluating '_this.props')
createReactClass$argument_0.touchableHandlePress
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Components\Touchable\TouchableOpacity.js:264:45
touchableHandlePress
[native code]:0
TouchableMixin._performSideEffectsForTransition
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Components\Touchable\Touchable.js:880:34
_performSideEffectsForTransition
[native code]:0
TouchableMixin._receiveSignal
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Components\Touchable\Touchable.js:779:44
_receiveSignal
[native code]:0
TouchableMixin.touchableHandleResponderRelease
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Components\Touchable\Touchable.js:490:24
touchableHandleResponderRelease
[native code]:0
invokeGuardedCallbackImpl
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:307:15
invokeGuardedCallback
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:531:36
invokeGuardedCallbackAndCatchFirstError
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:555:30
executeDispatch
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:722:42
executeDispatchesInOrder
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:744:20
executeDispatchesAndRelease
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:907:29
forEach
[native code]:0
forEachAccumulated
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:887:16
runEventsInBatch
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:932:21
runExtractedPluginEventsInBatch
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:1096:19
batchedUpdates$argument_0
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2796:6
batchedUpdates$1
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:18791:14
batchedUpdates
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2709:30
batchedUpdates$argument_0
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2794:17
receiveTouches
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2870:28
__callFunction
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:436:47
__guard$argument_0
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:111:26
__guard
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:384:10
__guard$argument_0
D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:110:17
callFunctionReturnFlushedQueue
[native code]:0
You have a function component with the props argument:
function CupertinoButtonSuccess(props) {
// ...
}
Inside, you're using this.props.navigation.goBack(). But this.props is not available in function components. You need to change it to use props.navigation.goBack() (without this).
There are things you need to know about react navigation and especially the stack navigation that you're using. The current version is navigation 5.
It allows you to navigate between screens which are components passed
down to the react navigation's file, let call that configuration file
App.js. In your case, your screens are "Home" and "Login", which
means that you should have the Home.js and Login.js components or
functions set somewhere in your projet.
//This is the minimum configuration you should have for App.js
// Watch out, the '#' is very important for navigation 5
import React from 'react';
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
import Home from './Home';
import Login from './Login';
const Stack = createStackNavigator();
export default class App extends React.Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName='Home'>
<Stack.Screen name='Home' component={Home} />
<Stack.Screen name='Login' } component={Login} />
</Stack.Navigator>
</NavigationContainer>
);
}
}
Your Login.js component is just like you did, but you should pass the navigation props to CupertinoButtonSuccess and CupertinoButtonWarnings, otherwise they can't automatically access the navigation props because you have not defined them as sceens in the navigation configuration file. To do that you just have this in the render method of Login.js
render(){
return(
<CupertinoButtonSuccess navigation={navigation} />
<CupertinoButtonWarning1 navigation={navigation} />
);
}
instead of
render(){
return(
<CupertinoButtonSuccess Navigation={this.props.navigation}
... > </CupertinoButtonSuccess>
<cupertinoButtonWarning1 Navigation={this.props.navigation}
... >
</cupertinoButtonWarning1>
);
}
(You even never close a custom component like that in react native. Only the build-in react native components such us View, Text have closing Tags like
"<View></View>" or "<Text></Text>",
but here is a custom component because it belongs to you alone and not to all react native developpers. Additionaaly you imported "CupertinoButtonWarning1" with begining capital letter "C" and now calling it as "cupertinoButtonWarning1" was another mistake, but I hope that was just typing errors.
Now about how to make CupertinoButtonSuccess class component instead of function based component, you will need to create two class based components, one for CupertinoButtonSuccess.js and the second cupertinoButtonWarning1.js because you can't render two class based components from the same single component.
// So for CupertinoButtonSuccess.js
import React, { Component } from "react";
import { StyleSheet, TouchableOpacity, Text, Button } from "react-native";
//You never need to be calling { createStackNavigator } here again because //CupertinoButtonSuccess.js is not a screen
export default class CupertinoButtonSuccess extends Component {
render(){
return (
<TouchableOpacity
onPress={() => this.props.navigation.goBack('Home')}
style={[styles.container, props.style]}>
<Text style={styles.caption}>{props.text1 || "Button"}</Text>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
//Your style here
});
//For CupertinoButtonWarning1.js you do same.
Finally and for the sake of completness, there is another way to use navigation props straight in the CupertinoButtonSuccess.js and CupertinoButtonWarning1 themselves, without waiting for Loging.js to pass it to them, it's by importing "useNavigation" like this in CupertinoButtonSuccess.js and CupertinoButtonWarning1.js :
import { useNavigation } from '#react-navigation/native';
This way you have access to the navigation props even from CupertinoButtonSuccess.js and CupertinoButtonWarning1.js.
The documentation about this is here https://reactnavigation.org/docs/connecting-navigation-prop/
Hopefully the script bellow will show roughly what I am trying to achieve.
But essentially, using a string stored in a state, be able to have a component holder dynamically load different components on change.
So you will see 2 component imported at the top (but ideally these could be a 100 different ones.
A currentSlide state that holds the string name of the component.
And a SlideLoader component that would ideally load imported components based on a string name.
Then the button's switch the component through resetting the state name.
Thank you!
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
} from 'react-native';
import SlideA from './slideA';
import SlideB from './slideB';
const styles = StyleSheet.create({
dummyContainer: {
flex: 0,
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
backgroundColor: '#999999',
},
buttonHolder: {
position: 'absolute',
top: 4,
left: 0,
},
button: {
height: 50,
width: 300,
backgroundColor: 'red',
marginBottom: 4,
textAlignVertical: 'center',
textAlign: 'center',
fontWeight: 'bold',
},
});
export default class Switcher extends Component {
constructor(props, context) {
super(props, context);
let state = {
currentSlide: 'SlideA',
}
}
render() {
// obvisously wrong part...
let SlideLoader = this.state.currentSlide;
// end of obvisously wrong part...
return (
<View
style={[
styles.dummyContainer,
]}
>
<SlideLoader />
<View
style={styles.buttonHolder}
>
<Text
onPress={() => {
console.log('SLID A');
setState({ currentSlide: 'SlideA' });
}}
style={[styles.button]}
>
Slide A
</Text>
<Text
onPress={() => {
console.log('SLID B');
setState({ currentSlide: 'SlideB' });
}}
style={[styles.button]}
>
Slide B
</Text>
</View>
</View>
);
}
}
ok here we go :
render() {
let SlideLoader;
if(this.state.currentSlide == 'SlideA')
SlideLoader=<SlideA />
else
SlideLoader=<SlideB />
return (
<View
style={[
styles.dummyContainer,
]}
>
{SlideLoader}
<View
style={styles.buttonHolder}
>
<Text
onPress={() => {
console.log('SLID A');
setState({ currentSlide: 'SlideA' });
}}
style={[styles.button]}
>
Slide A
</Text>
<Text
onPress={() => {
console.log('SLID B');
setState({ currentSlide: 'SlideB' });
}}
style={[styles.button]}
>
Slide B
</Text>
</View>
</View>
);
}
Cheers:)
I would like to ask, is there any solution to come out with something like Messenger(Mobile App) searching function? The route is having a basic view elements. When user is typing in some words, the search will start to function, within the same screen, another view overlap to show the filter list. I had tried to use react-native-overlap module but it not work well.
var React = require ('react-native');
var {
Text, View, StyleSheet, TextInput, Dimensions, Image, Platform, ScrollView, ReactNative, DeviceEventEmitter,TouchableOpacity
} = React;
var NavigationBar = require ('../Components/NavigationBar');
var SearchBarFromNodeModule = require ('react-native-search-bar');
var Overlay=require('react-native-overlay');
var Recent = React.createClass({
getInitialState(){
return {
isVisible:'aa',
};
},
onNameChanged(e){
//todo something here
// alert('asd');
},
render (){
return (
<View>
<View style={styles.navbarContainer}>
<SearchBarFromNodeModule ref='searchBar' placeholder='Search' showsCancelButton={true} onChange={this.onNameChanged} />
</View>
<View style={{flex:1, flexDirection:'column'}}>
<View style={{backgroundColor:'#F4FA58',flex:1,height:40}}/>
<View style={{backgroundColor:'#58FAF4',flex:1,height:40}}/>
<View style={{backgroundColor:'#F4FA58',flex:1,height:40}}/>
<View style={{backgroundColor:'#58FAF4',flex:1,height:40}}/>
<View style={{backgroundColor:'#F4FA58',flex:1,height:40}}/>
<View style={{backgroundColor:'#58FAF4',flex:1,height:40}}/>
</View>
</View>
);
},
});
var styles=StyleSheet.create({
navbarContainer: {
height: 65,
paddingTop: 20,
},
button:{
height:40,
textAlign:'center',
fontSize:18,
marginBottom:10,
marginTop:10,
color:'blue',
}`enter code here`
});
module.exports = Recent;
Now there is some color boxes after the search bar, when user is typing something, onChange function will take place. But I have no idea how to overlap the color boxes.
This gets the job mostly done. The only issue is the search results box renders under the text view below the search input. This could be corrected in a few ways but I personally would likely look to the zIndex feature introduced in 0.30 that is coming out soon.
https://rnplay.org/apps/CJNPWg
import React from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TextInput
} from 'react-native';
class SearchResults extends React.Component {
render() {
if (this.props.search.toUpperCase() !== 'BAM') {
return null;
}
return (
<View style={styles.searchResults}>
<Text>
Do whatever your heart desires here... Might I recomend a list view??
</Text>
</View>
);
}
}
class SearchBox extends React.Component {
render() {
return (
<View>
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
value={this.props.search}
onChangeText={this.props.onChange}
placeholder="Try 'BAM'!"
/>
<SearchResults search={props.search} />
</View>
);
}
}
class SampleApp extends React.Component {
state = {
currentSearch: ''
};
onCurrentSearchChange(text) {
this.setState({
currentSearch: text
});
}
render() {
return (
<View style={styles.container}>
<Text>Enter your search</Text>
<SearchBox search={this.state.currentSearch} onChange={this.onCurrentSearchChange.bind(this)} />
<Text>Some text below the search box...</Text>
</View>
);
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 30
},
searchResults: {
position: 'absolute',
backgroundColor: 'white',
borderColor: 'black',
borderWidth: 1
}
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);