Overlapping items in React Native FlatList - react-native

I'm trying to make a list of items in FlatList overlap over each other like a stack of cards, but using a negative margin the item gets cut off, using "left: -20" does as well.
The image component is rather simple with round border:
export default class ProfilePicture extends React.Component {
render () {
let size = this.props.size || 50
return (
<Image
source={{ uri: this.props.picture }}
style={{
backgroundColor: 'rgba(12, 94, 20, 0.5);',
width: size,
height: size,
borderRadius: size / 2
}}
/>
)
}
}
And in the list is where I try to accomplish the overlap:
export default class RidersListCompact extends Component {
state = {
users: []
}
...
renderItem = ({ item: user, index }) => {
return <View style={styles.itemContainer}>
<ProfilePicture
picture={user.picture}
size={Layout.window.hp(6)}
/>
</View>
}
render () {
return (
<FlatList
renderItem={this.renderItem}
data={this.state.users}
keyExtractor={(user) => 'user_' + user.id}
horizontal
inverted
style={{ ...styles.container, ...this.props.style }}
/>
)
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row-reverse'
},
itemContainer: {
marginRight: -Layout.window.hp(2),
width: Layout.window.hp(6),
height: Layout.window.hp(6),
backgroundColor: 'rgba(0,0,0,0);'
}
})
I tried setting different zIndex on each item but haven't had much luck, is there a way to overlap images/components in FlatList?
Cheers!

Make use of Flex. seperate Items by putting then in flex direact row wise. use Props from flex. Flex has following props available
alignContent
alignItems
alignSelf
aspectRatio
borderBottomWidth
borderEndWidth
borderLeftWidth
borderRightWidth
borderStartWidth
borderTopWidth
borderWidth
bottom
direction
display
end
flex
flexBasis
flexDirection
flexGrow
flexShrink
flexWrap
height
justifyContent
left
margin
marginBottom
marginEnd
marginHorizontal
marginLeft
marginRight
marginStart
marginTop
marginVertical
maxHeight
maxWidth
minHeight
minWidth
overflow
padding
paddingBottom
paddingEnd
paddingHorizontal
paddingLeft
paddingRight
paddingStart
paddingTop
paddingVertical
position
right
start
top
width
zIndex

If you want to overlap images you should use position style in your styles. You need to set position to absolute and set left, right, top, bottom values.
More information

Related

Get coordinates of touch event relative to Image

I have an image centered on the screen. I need to make it touchable and I need to get the coordinates of the touch event relative to the image. I have wrapped my image in a TouchableOpacity to make it touchable. The problem is that the touch coordinates are relative to the TouchableOpacity and not the Image. The TouchableOpacity is taking up the entire screen but the Image is centered inside it.
I either need to make my TouchableOpacity the same size as the Image, or I need to know the offset of the Image within the TouchableOpacity.
I have tried using OnLayout and the NativeEvent object to get the position of the Image within it's parent but it just returns 0,0.
const {width, height} = Dimensions.get("window");
class Inspection extends React.Component {
handlePress(evt) {
// do stuff
...
}
render() {
return (
<View style={{flex:1, backgroundColor:'#fff'}}>
<TouchableOpacity
onPress={(evt) => this.handlePress(evt)}
style={{backgroundColor: '#3897f0'}}
>
<Image
onLayout={({nativeEvent}) => {
console.log(nativeEvent.layout);
}}
source={require('../../images/wireframe-car.jpg')}
resizeMode='contain'
style={{
maxHeight: height,
maxWidth: width
}}
/>
</TouchableOpacity>
</View>
);
}
}
Console Output:
{height: 683.4285888671875, width: 411.4285583496094, y: 0, x: 0}
I've added a backgroundColor to TouchableOpacity so you can see that it takes up the entire screen.
Is there another way of doing this?
TouchableOpacity would be the same size as of the Image because you haven't given any height to it, you simply need to assign onLayout prop to your TouchableOpacity like this
<View
style={{ flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center' }}>
<TouchableOpacity
onLayout={({ nativeEvent }) => {
console.log(nativeEvent.layout)
}}
style={{}}
onPress={evt => this.handlePress(evt)}>
<Image
source={require('../../images/wireframe-car.jpg')}
resizeMode="contain"
style={{
maxWidth: '100%',
}}
/>
</TouchableOpacity>
</View>
This will give you the exact x and y of Image.
Update
The problem is also with image size, since the image size is quite big so it takes the height of the device and we get x:0 and y:0, in order to resolve this issue we can give the Image component a static height or calculate its height according to width. We can get width and height image from local path like this:
let imageUri = Image.resolveAssetSource(require('../../images/wireframe-car.jpg').uri)
Image.getSize(imageUri , (width, height) => {
console.log(`The image dimensions are ${width}x${height}`);
}, (error) => {
console.error(`Couldn't get the image size: ${error.message}`);
});

React Native: Correct scrolling in horizontal FlatList with Item Separator

ReactNative: v0.52.0
Platform: iOS
My FlatList code:
<FlatList
horizontal
pagingEnabled={true}
showsHorizontalScrollIndicator={false}
legacyImplementation={false}
data={this.props.photos}
renderItem={item => this.renderPhoto(item)}
keyExtractor={photo => photo.id}
ItemSeparatorComponent={this.itemSeparatorComponent}
/>
Item separator code:
itemSeparatorComponent = () => {
return <View style = {
{
height: '100%',
width: 5,
backgroundColor: 'red',
}
}
/>
}
And finally FlatList item component:
renderPhoto = ({ item, index }) => {
return (
<View style = {{ width: SCREEN_WIDTH, height: 'auto' }}>
<FastImage
style = { styles.photo }
resizeMode = { FastImage.resizeMode.contain }
source = {{ uri: item.source.uri }}
/>
</View>
)
}
But when scrolling, the FlatList makes an offset to the separator but not to the left edge of item:
And with each new element the FlatList adds the width of the all previous separators to offset:
How to make the FlatList component consider the width of the separator component in horizontal scrolling and make proper offset?
I had the same use-case. For anyone looking for a solution, here it is.
Step 1) Don't use ItemSeparatorComponent prop. Instead, render it inline in your renderItem component.
Step 2) (Key-point). Specify the width and height in the style prop of the FlatList. The width, in your case, should be SCREEN_WIDTH + 5.
Then Flatlist will automatically move the entire screen (photo + separator) away when pagination is enabled. So now your code should be like so:-
<FlatList
horizontal
pagingEnabled={true}
showsHorizontalScrollIndicator={false}
legacyImplementation={false}
data={this.props.photos}
renderItem={item => this.renderPhoto(item)}
keyExtractor={photo => photo.id}
style={{width: SCREEN_WIDTH + 5, height:'100%'}}
/>
Render photo code:-
renderPhoto = ({ item, index }) => {
return (
<View style = {{ width: SCREEN_WIDTH + 5, height: 'auto',
flexDirection:'row'}}>
<FastImage
style = { styles.photo }
resizeMode = { FastImage.resizeMode.contain }
source = {{ uri: item.source.uri }}
/>
{this. itemSeparatorComponent()}
</View>
)}
Item separator code:
itemSeparatorComponent = () => {
return <View style = {
{
height: '100%',
width: 5,
backgroundColor: 'red',
}
}
/>
}
If you still can't figure it out, then look at this component:
https://github.com/zachgibson/react-native-parallax-swiper
Try to go into the implementation, you will see that this guy has provided width and height to the Animated.ScrollView.
https://github.com/zachgibson/react-native-parallax-swiper/blob/master/src/ParallaxSwiper.js
Line number: 93 - 97
The top-level view you're returning in the renderPhoto function has a width of SCREEN_WIDTH, yet the ItemSeparatorComponent, which renders in between each item, is taking up a width of 5 as per your style definition. Consequently, for each additional item you scroll to, that initial offset will become 5 more pixels on the left.
To fix this, you can either remove the ItemSeparatorComponent completely, (as you already have pagingEnabled set to true), or set the width of the top-level view returned in renderPhoto equal to SCREEN_WIDTH - 2.5. That way you'll see half of the item separator on the right edge of one photo and the other half on the left edge of the next photo.
Actually, one other possible solution could be to remove the item separator, set the renderPhoto View's width to SCREEN_WIDTH + 5, and then include these additional properties inside the style: {paddingRight: 5, borderRightWidth: 5, borderRightColor: 'red'}. That way the red separator won't be visible until scrolling left and right, because of the pagingEnabled property.

Horizontal FlatList React Native with different height of items

I have a little problem with the FlatList Component in react native. In the FlatList are items with different height. Here is a little example of what i have:
example FlatL
The first problem is that all items are positioned at the top. I want to position all items at the bottom.
The second problem is that the height of the FlatList is always the height of the biggest item. So you can also scroll to another item in the white area of a small item...
here my code:
import React from "react";
import {
Text,
View,
Dimensions,
StyleSheet,
ListView,
TouchableOpacity,
Animated,
Image,
FlatList
} from "react-native";
import glamorous, { ThemeProvider } from "glamorous-native";
import theme from "../theme";
const { height, width } = Dimensions.get("window");
const cards = [
{
id: 1,
color: "red",
height: 400
},
{
id: 2,
color: "blue",
height: 300
},
{
id: 3,
color: "yellow",
height: 200
}
];
class Test extends React.Component {
render() {
return (
<View style={{ bottom: 0 }}>
<FlatList
ref={elm => (this.flatList = elm)}
showsHorizontalScrollIndicator={false}
data={cards}
pagingEnabled={true}
horizontal={true}
keyExtractor={item => item.id}
renderItem={({ item }) => (
<View
style={{
height: item.height,
width: width,
backgroundColor: item.color
}}
/>
)}
/>
</View>
);
}
}
export default Test;
Has anyone a solution?
You can change the position of each item by setting the contentContainerStyle property of the FlatList itself. But the height of the FlatList will always have to be the height of the largest component inside it.
I solved this with onViewableItemsChanged prop
viewabilityConfig={{itemVisiblePercentThreshold: 50}}
onViewableItemsChanged={this.onViewableItemsChanged}
onViewableItemsChanged = ({ viewableItems }) => {
let index = viewableItems[0].index;
this.setState({ indexOfImages: index, heightOfImages: SCREEN_WIDTH * (viewableItems[0].item.height / viewableItems[0].item.width) });
}
We have width and height of the items in its data so I'm taking width and height of the visible item on the screen and do some calculations and I'm using this.state.heightOfImages in flatlist height like this
height: this.state.heightOfImages == undefined ? SCREEN_WIDTH * (images[0].height / images[0].width) : this.state.heightOfImages
You can just wrap the content of each card in another <View> element with styles={{ minHeight: 200, maxHeight: 300 }} and it will work fine!

React Native FlatList with columns, Last item width

I'm using a FlatList to show a list of items in two columns
<FlatList style={{margin:5}}
data={this.state.items}
numColumns={2}
keyExtractor={(item, index) => item.id }
renderItem={(item) => <Card image={item.item.gallery_image_url} text={item.item.name}/> }
/>
The card component is just a view with some styles:
<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', height: 130}} ></View>
It is working fine, but if the number of items is odd, the last row only contains one item and that item stretches to the full width of the screen.
How can I set the item to the same width of the others?
for your case use flex: 1/2
therefore: Your item should have flex of 1/(number of columns) if you have 3 columns your item should have flex:1/3
Theres a few things you can try here.
A) Setting a pre-defined width for the card ( Maybe equal to the height you've set? ). Then you can use alignItems in order to have the card positioned in the middle or on the left - Unsure as to which you wanted here.
B) If there are an even number of cards, you could add an empty View at the end in order to fill this space. I find this method pretty clunky but useful when trying to leave space for future elements.
C) Simply use alignItems: 'space-between, i like to use this to center items, but you would have to define the width, or use something like flex:0.5
I suggest researching more into flexbox to help you with this, as it is hard to tell the context of this situation. I'm assuming the above methods will help, but if not, here are some links for you to look at -
A Complete Guide to Flexbox (CSS Tricks)
Layout with Flexbox (React Native)
Video Tutorial (Youtube) Link Broken
Hope this helps. If you need any further clarification - just ask
This is the cleanest way to style a FlatList with columns and spaced evenly:
<FlatList style={{margin:5}}
numColumns={2} // set number of columns
columnWrapperStyle={style.row} // space them out evenly
data={this.state.items}
keyExtractor={(item, index) => item.id }
renderItem={(item) => <Card image={item.item.gallery_image_url} text={item.item.name}/> }
/>
const style = StyleSheet.create({
row: {
flex: 1,
justifyContent: "space-around"
}
});
You can try to get the current width of the device via Dimensions, do some math based on the number of columns you want to render, minus off the margins and set that as the minWidth and maxWidth.
For example:
const {height, width} = Dimensions.get('window');
const itemWidth = (width - 15) / 2;
<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', minWidth: {this.itemWidth}, maxWidth: {this.itemWidth}, height: 130}} ></View>
The reason for it is your Card have style flex: 1, so it will try to expand all the space remain.
You can fix it by add maxWidth: '50%' to your Card style
<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', height: 130, maxWidth: '50%'}} ></View>
#Emilius Mfuruki suggestion is good, but if you have text with varying length it doesn't work perfectly. Then use this width inside your item view:
const {height, width} = Dimensions.get('window');
const itemWidth = (width - (MarginFromTheSide * 2 + MarginInBetween * (n-1))) / n;
In FlatList use:
columnWrapperStyle={{
flex: 1,
justifyContent: 'space-evenly',
}}
Works perfectly.
The simplest solution is do the math.
Imagine we have 2 View for each Row and we want to give 10 margin to every side it will look something like that:
As you see in the image above each View have 2 margins in horizontal. (inside of red rectangle)
So we have to subtract the product of margin, number of column and 2 from the width.
import { Dimensions } from 'react-native';
const {width} = Dimensions.get("window")
const column = 2
const margin = 10
const SIZE = (width - (margin * column * 2)) / column
<View style={{ margin: 10, width: SIZE }} ></View>
I tried some of the solutions above but I still had some problems with the margins on the last item (2 columns list).
My solution was simply wrapping the item into a parent container, leaving the original container with flex: 1 and the parent container of the item with flex: 0.5 so it would take the margin correctly.
itemContainer: {
flex: 0.5,
},
itemSubContainer: {
flex: 1,
marginHorizontal: margin,
},
A simple way with flex
<FlatList style={{margin:5}}
data={this.state.items}
numColumns={2}
keyExtractor={(item, index) => item.id }
renderItem={({item, index}) => {
const lastItem = index === this.state.items.length - 1;
return (
<View style={{flex: lastItem ? 1 / 2 : 1 }}>
<Card image={item.gallery_image_url} text={item.name}/>
</View>
)}}
/>
You can use ListFooterComponent={this.renderFooter}
None of the above answers have worked perfectly for me so I post my own answer:
works with padding and margins
the last element will always have the correct size
<FlatList
data={data}
numColumns={2}
renderItem={({item, index}) => {
const lastItem = index === data.length - 1;
return (
<View style={{flex: 1, padding: 8, maxWidth: lastItem ? '50%' : '100%' }}>
...
</View>
)}}
/>
Note: change maxWidth according to number of columns
Result:
just use flex:0.5 and width:'50%'
Create an array with odd number of images in it, like:
const images = [
require('./../...jpg'),
require('./../...jpg'),
require('./../...jpg'),
require('./../...jpg'),
require('./../...jpg'),
];
And then, use the code given below,
const App = () => {
const _renderItem = ({ item, index }) => (
<Image
source={item}
style={{
width: '50%',
height: 200,
}}
resizeMode="cover"
/>
);
return (
<View style={{flex: 1, marginHorizontal: 10,}}>
<FlatList
columnWrapperStyle={{ justifyContent: 'space-between' }}
keyExtractor={(_, index)=> index.toString()}
data={images}
numColumns={2}
renderItem={_renderItem}
/>
</View>
)
};
export default App;
Working Example

How to set background color of view transparent in React Native

This is the style of the view that i have used
backCover: {
position: 'absolute',
marginTop: 20,
top: 0,
bottom: 0,
left: 0,
right: 0,
}
Currently it has a white background. I can change the backgroundColor as i want like '#343434' but it accepts only max 6 hexvalue for color so I cannot give opacity on that like '#00ffffff'. I tried using opacity like this
backCover: {
position: 'absolute',
marginTop: 20,
top: 0,
bottom: 0,
left: 0,
right: 0,
opacity: 0.5,
}
but it reduces visibility of view's content.
So any answers?
Use rgba value for the backgroundColor.
For example,
backgroundColor: 'rgba(52, 52, 52, 0.8)'
This sets it to a grey color with 80% opacity, which is derived from the opacity decimal, 0.8. This value can be anything from 0.0 to 1.0.
The following works fine:
backgroundColor: 'rgba(52, 52, 52, alpha)'
You could also try:
backgroundColor: 'transparent'
Try this backgroundColor: '#00000000'
it will set background color to transparent, it follows #rrggbbaa hex codes
Surprisingly no one told about this, which provides some !clarity:
style={{
backgroundColor: 'white',
opacity: 0.7
}}
Try to use transparent attribute value for making transparent background color.
backgroundColor: 'transparent'
You should be aware of the current conflicts that exists with iOS and RGBA backgrounds.
Summary: public React Native currently exposes the iOS layer shadow
properties more-or-less directly, however there are a number of
problems with this:
1) Performance when using these properties is poor by default. That's
because iOS calculates the shadow by getting the exact pixel mask of
the view, including any tranlucent content, and all of its subviews,
which is very CPU and GPU-intensive. 2) The iOS shadow properties do
not match the syntax or semantics of the CSS box-shadow standard, and
are unlikely to be possible to implement on Android. 3) We don't
expose the layer.shadowPath property, which is crucial to getting
good performance out of layer shadows.
This diff solves problem number 1) by implementing a default
shadowPath that matches the view border for views with an opaque
background. This improves the performance of shadows by optimizing for
the common usage case. I've also reinstated background color
propagation for views which have shadow props - this should help
ensure that this best-case scenario occurs more often.
For views with an explicit transparent background, the shadow will
continue to work as it did before ( shadowPath will be left unset,
and the shadow will be derived exactly from the pixels of the view and
its subviews). This is the worst-case path for performance, however,
so you should avoid it unless absolutely necessary. Support for this
may be disabled by default in future, or dropped altogether.
For translucent images, it is suggested that you bake the shadow into
the image itself, or use another mechanism to pre-generate the shadow.
For text shadows, you should use the textShadow properties, which work
cross-platform and have much better performance.
Problem number 2) will be solved in a future diff, possibly by
renaming the iOS shadowXXX properties to boxShadowXXX, and changing
the syntax and semantics to match the CSS standards.
Problem number 3) is now mostly moot, since we generate the shadowPath
automatically. In future, we may provide an iOS-specific prop to set
the path explicitly if there's a demand for more precise control of
the shadow.
Reviewed By: weicool
Commit: https://github.com/facebook/react-native/commit/e4c53c28aea7e067e48f5c8c0100c7cafc031b06
Adding reference of React-Native Version 0.64
Named colors
Named Colors: DOCS
In React Native you can also use color name strings as values.
Note: React Native only supports lowercase color names. Uppercase color names are not supported.
transparent#
This is a shortcut for rgba(0,0,0,0), same like in CSS3.
Hence you can do this:
background: {
backgroundColor: 'transparent'
},
Which is a shortcut of :
background: {
backgroundColor: 'rgba(0,0,0,0)'
},
In case you have hex color, you can convert it to rgba and set the opacity there:
const hexToRgbA = (hex, opacity) => {
let c;
if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) {
c = hex.substring(1).split('');
if (c.length === 3) {
c = [c[0], c[0], c[1], c[1], c[2], c[2]];
}
c = `0x${c.join('')}`;
return `rgba(${[(c >> 16) & 255, (c >> 8) & 255, c & 255].join(',')},${opacity})`;
}
throw new Error('Bad Hex');
};
const color = '#1f8b7f'; // could be a variable
return (
<View style={{ backgroundColor: hexToRgbA(color, 0.1) }} />
)
source that helped me
This will do the trick help you,
Add one View element and add style as below to that view
.opaque{
position:'absolute',
backgroundColor: 'black',
opacity: 0.7,
zIndex:0
}
The best way to use background is hex code #rrggbbaa but it should be in hex.
Eg: 50% opacity means 256/2 =128, then convert that value(128) in HEX that will be 80,use #00000080 80 here means 50% transparent.
Here is my solution to a modal that can be rendered on any screen and initialized in App.tsx
ModalComponent.tsx
import React, { Component } from 'react';
import { Modal, Text, TouchableHighlight, View, StyleSheet, Platform } from 'react-native';
import EventEmitter from 'events';
// I keep localization files for strings and device metrics like height and width which are used for styling
import strings from '../../config/strings';
import metrics from '../../config/metrics';
const emitter = new EventEmitter();
export const _modalEmitter = emitter
export class ModalView extends Component {
state: {
modalVisible: boolean,
text: string,
callbackSubmit: any,
callbackCancel: any,
animation: any
}
constructor(props) {
super(props)
this.state = {
modalVisible: false,
text: "",
callbackSubmit: (() => {}),
callbackCancel: (() => {}),
animation: new Animated.Value(0)
}
}
componentDidMount() {
_modalEmitter.addListener(strings.modalOpen, (event) => {
var state = {
modalVisible: true,
text: event.text,
callbackSubmit: event.onSubmit,
callbackCancel: event.onClose,
animation: new Animated.Value(0)
}
this.setState(state)
})
_modalEmitter.addListener(strings.modalClose, (event) => {
var state = {
modalVisible: false,
text: "",
callbackSubmit: (() => {}),
callbackCancel: (() => {}),
animation: new Animated.Value(0)
}
this.setState(state)
})
}
componentWillUnmount() {
var state = {
modalVisible: false,
text: "",
callbackSubmit: (() => {}),
callbackCancel: (() => {})
}
this.setState(state)
}
closeModal = () => {
_modalEmitter.emit(strings.modalClose)
}
startAnimation=()=>{
Animated.timing(this.state.animation, {
toValue : 0.5,
duration : 500
}).start()
}
body = () => {
const animatedOpacity ={
opacity : this.state.animation
}
this.startAnimation()
return (
<View style={{ height: 0 }}>
<Modal
animationType="fade"
transparent={true}
visible={this.state.modalVisible}>
// render a transparent gray background over the whole screen and animate it to fade in, touchable opacity to close modal on click out
<Animated.View style={[styles.modalBackground, animatedOpacity]} >
<TouchableOpacity onPress={() => this.closeModal()} activeOpacity={1} style={[styles.modalBackground, {opacity: 1} ]} >
</TouchableOpacity>
</Animated.View>
// render an absolutely positioned modal component over that background
<View style={styles.modalContent}>
<View key="text_container">
<Text>{this.state.text}?</Text>
</View>
<View key="options_container">
// keep in mind the content styling is very minimal for this example, you can put in your own component here or style and make it behave as you wish
<TouchableOpacity
onPress={() => {
this.state.callbackSubmit();
}}>
<Text>Confirm</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
this.state.callbackCancel();
}}>
<Text>Cancel</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
</View>
);
}
render() {
return this.body()
}
}
// to center the modal on your screen
// top: metrics.DEVICE_HEIGHT/2 positions the top of the modal at the center of your screen
// however you wanna consider your modal's height and subtract half of that so that the
// center of the modal is centered not the top, additionally for 'ios' taking into consideration
// the 20px top bunny ears offset hence - (Platform.OS == 'ios'? 120 : 100)
// where 100 is half of the modal's height of 200
const styles = StyleSheet.create({
modalBackground: {
height: '100%',
width: '100%',
backgroundColor: 'gray',
zIndex: -1
},
modalContent: {
position: 'absolute',
alignSelf: 'center',
zIndex: 1,
top: metrics.DEVICE_HEIGHT/2 - (Platform.OS == 'ios'? 120 : 100),
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
height: 200,
width: '80%',
borderRadius: 27,
backgroundColor: 'white',
opacity: 1
},
})
App.tsx render and import
import { ModalView } from './{your_path}/ModalComponent';
render() {
return (
<React.Fragment>
<StatusBar barStyle={'dark-content'} />
<AppRouter />
<ModalView />
</React.Fragment>
)
}
and to use it from any component
SomeComponent.tsx
import { _modalEmitter } from './{your_path}/ModalComponent'
// Some functions within your component
showModal(modalText, callbackOnSubmit, callbackOnClose) {
_modalEmitter.emit(strings.modalOpen, { text: modalText, onSubmit: callbackOnSubmit.bind(this), onClose: callbackOnClose.bind(this) })
}
closeModal() {
_modalEmitter.emit(strings.modalClose)
}
Hope I was able to help some of you, I used a very similar structure for in-app notifications
Happy coding