Skip to content

Commit

Permalink
Merge pull request #767 from shoutem/release/6.1.0
Browse files Browse the repository at this point in the history
Release/6.1.0 -> master
  • Loading branch information
sstimac authored Nov 21, 2022
2 parents d2e3b07 + 7020b86 commit f9bdf33
Show file tree
Hide file tree
Showing 18 changed files with 2,868 additions and 500 deletions.
3 changes: 3 additions & 0 deletions components/Icon/assets/checkmark-oval.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions components/Icon/assets/checkmark-round.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions components/Icon/assets/error-rectangle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions components/Icon/assets/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import checkboxOff from './checkbox-off.svg';
import checkboxOn from './checkbox-on.svg';
import checkboxRectangleOff from './checkbox-rectangle-off.svg';
import checkboxRectangleOn from './checkbox-rectangle-on.svg';
import checkmarkOval from './checkmark-oval.svg';
import checkmarkRound from './checkmark-round.svg';
import clearText from './clear-text.svg';
import clock from './clock.svg';
import close from './close.svg';
Expand All @@ -32,6 +34,7 @@ import edit from './edit.svg';
import email from './email.svg';
import equalizer from './equalizer.svg';
import error from './error.svg';
import errorrRectangle from './error-rectangle.svg';
import events from './events.svg';
import exitToApp from './exit-to-app.svg';
import eye from './eye.svg';
Expand Down Expand Up @@ -137,6 +140,8 @@ export const defaultConfig = [
{ name: 'checkbox-on', icon: checkboxOn },
{ name: 'checkbox-rectangle-off', icon: checkboxRectangleOff },
{ name: 'checkbox-rectangle-on', icon: checkboxRectangleOn },
{ name: 'checkmark-oval', icon: checkmarkOval },
{ name: 'checkmark-round', icon: checkmarkRound },
{ name: 'clear-text', icon: clearText },
{ name: 'clock', icon: clock },
{ name: 'close', icon: close },
Expand All @@ -152,6 +157,7 @@ export const defaultConfig = [
{ name: 'email', icon: email },
{ name: 'equalizer', icon: equalizer },
{ name: 'error', icon: error },
{ name: 'error-rectangle', icon: errorrRectangle },
{ name: 'events', icon: events },
{ name: 'exit-to-app', icon: exitToApp },
{ name: 'eye', icon: eye },
Expand Down
100 changes: 100 additions & 0 deletions components/ToastMessage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Shoutem UI Toasts :bread:

New component used for multiple types of alerts, or simple action prompts. The component is based on the [react-native-toast-message ](https://github.com/calintamas/react-native-toast-message)package, with our wrapper implementation defining custom styled toast types

> You are still free to use the react-native-toast-message show/hide methods directly, through our default export, if you so desire.
## Usage

Most of the time, you will want to use one of the four standard methods of showing a toast using this package.

- Toast.showInfo
- Toast.showAlert
- Toast.showError
- Toast.showSuccess

- Toast.show() and Toast.hide() methods are identical to the ones in the parent library. So if you want to use your own components for alerts, you can do it just like you would normally.

Each of these accepts same set or props / params, but implements different styling and color schemes, according to it's semantic significance. Below are a couple of examples of commonly used methods.

```jsx
import { Toast } from '@shoutem/ui';
...
Toast.showInfo({
title: 'Hello world!',
message: `This is a message!`,
iconSource: {
uri: 'https://townsquare.media/site/341/files/2012/05/Mr.-Trololo.jpg',
},
});
...
```

```jsx
import { Toast } from '@shoutem/ui';
...
Toast.showAlert({
title: 'Stop',
message: `Hammer time`,
iconSource: require('../assets/actionIcon.png'),
cancelButtonText: 'absolutely not',
confirmButtonText: `Hammer zeit!`,
onCancel: Toast.hide,
onConfirm: () => {
console.log('A man of culture....');
Toast.hide();
}
});
...
```

```jsx
import { Toast } from '@shoutem/ui';
...
Toast.showError({
title: 'Error',
message: `We've failed to charge your credit card. Please check your CC data`,
iconName: 'error',
confirmButtonText: `Take me to payment details`,
onConfirm: () => {
navigateTo('PaymentDetailsScreen');
Toast.hide();
}
autoHide: false,
});
...
```


### Props

Currently supported props mainly include "native" props from the parent library, with both, a few exclusions and a some additions. Also, you can pass any kind of custom prop you want, and it will be passed in to your custom toast component

| **Name** | **Type** | **Default** | **Description** |
|---------------------------------------------|-------------------|-------------|----------------------------------------------------------------------------------------------------------------------------------|
| title | String | Required | Title of the toast message |
| message | String | Required | Description of the toast message |
| iconName | String | Info | Name of the existing icon in the UI toolkit that will be used as a leading image |
| iconSource | ImageSourceType | undefined | Standard image source ( uri object, direct require, ... ). If this prop is passed in, it will take presedence over iconName prop |
| durationIndicator | Bool | true | Displays the duration indicator line below the toast, in the duration of the `visibilityTime` prop |
| onConfirm | Function | undefined | Callback called when pressing the confirm button |
| onCancel | Function | undefined | Callback called when pressing the cancel button |
| confirmButtonText | String | undefined | |
| cancelButtonText | String | undefined | |
| `-- props supported from parent library --` | | | |
| position | `top` or `bottom` | top | |
| visibilityTime | Number | 4000 | How long is the toast displayed |
| autoHide | Bool | true | Hide automatically after visibilityTime has expired |
| topOffset | Number | 40 | |
| bottomOffset | Number | 40 | |
| keyboardOffset | Number | 10 | |
| onShow | Function | | |
| onHide | Function | | |
| onPress | Function | | |

## BaseToast

This component also exports our base component that contains all of the internal logic that understand how to compose and handle toast message. If you'd like to create a new Toast component, feel free to use the BaseToast, and inject `customToastStyle` prop that will be merged with the default styles, and / or any other prop manipualtion you require.



18 changes: 18 additions & 0 deletions components/ToastMessage/components/ActionToast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import { connectStyle } from '@shoutem/theme';
import BaseToast from './BaseToast';

function ActionToast({ style, isVisible, props }) {
return (
<BaseToast
customToastStyle={style}
iconName="checkmark-oval"
isVisible={isVisible}
{...props}
/>
);
}

ActionToast.propTypes = BaseToast.propTypes;

export default connectStyle('shoutem.ui.ActionToast')(ActionToast);
123 changes: 123 additions & 0 deletions components/ToastMessage/components/BaseToast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import React, { useMemo } from 'react';
import _ from 'lodash';
import PropTypes from 'prop-types';
import { connectStyle } from '@shoutem/theme';
import { Icon, Image, Text, Touchable, View } from '@shoutem/ui';
import ToastProgressBar from './ToastProgressBar';

function BaseToast({
message,
title,
style,
iconSource,
iconName,
onConfirm,
confirmButtonText,
onCancel,
cancelButtonText,
durationIndicator,
visibilityTime,
customToastStyle,
isVisible,
}) {
const hasConfirmButton = onConfirm && confirmButtonText;
const hasCancelButton = onCancel && cancelButtonText;
const resolvedStyle = useMemo(() => _.merge(style, customToastStyle), [
style,
customToastStyle,
]);

return (
<View style={resolvedStyle.container}>
<View style={resolvedStyle.detailsContainer}>
{iconSource && (
<Image source={iconSource} style={resolvedStyle.image} />
)}
{!iconSource && <Icon name={iconName} style={resolvedStyle.icon} />}
<View style={resolvedStyle.textContainer}>
{title && <Text style={resolvedStyle.title}>{title}</Text>}
{message && <Text style={resolvedStyle.message}>{message}</Text>}
</View>
</View>
{(hasConfirmButton || hasCancelButton) && (
<View style={resolvedStyle.buttonContainer}>
{hasCancelButton && (
<Touchable
style={[
resolvedStyle.button,
resolvedStyle.cancelButton,
!hasConfirmButton && resolvedStyle.fullWidthButton,
]}
onPress={onCancel}
>
<Text
style={[
resolvedStyle.buttonText,
resolvedStyle.cancelButtonText,
]}
>
{cancelButtonText}
</Text>
</Touchable>
)}
{hasConfirmButton && (
<Touchable
style={[
resolvedStyle.button,
resolvedStyle.confirmButton,
!hasCancelButton && resolvedStyle.fullWidthButton,
]}
onPress={onConfirm}
>
<Text
style={[
resolvedStyle.buttonText,
resolvedStyle.confirmButtonText,
]}
>
{confirmButtonText}
</Text>
</Touchable>
)}
</View>
)}
<ToastProgressBar
duration={visibilityTime}
color={resolvedStyle.progressBar.color}
visible={isVisible && durationIndicator}
/>
</View>
);
}

BaseToast.propTypes = {
isVisible: PropTypes.bool.isRequired,
style: PropTypes.object.isRequired,
cancelButtonText: PropTypes.string,
confirmButtonText: PropTypes.string,
customToastStyle: PropTypes.object,
durationIndicator: PropTypes.bool,
iconName: PropTypes.string,
iconSource: PropTypes.any,
message: PropTypes.string,
title: PropTypes.string,
visibilityTime: PropTypes.number,
onCancel: PropTypes.func,
onConfirm: PropTypes.func,
};

BaseToast.defaultProps = {
customToastStyle: {},
title: undefined,
message: undefined,
confirmButtonText: undefined,
cancelButtonText: undefined,
onCancel: undefined,
onConfirm: undefined,
durationIndicator: true,
iconName: 'about',
iconSource: undefined,
visibilityTime: 4000,
};

export default connectStyle('shoutem.ui.BaseToast')(BaseToast);
18 changes: 18 additions & 0 deletions components/ToastMessage/components/ErrorToast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import { connectStyle } from '@shoutem/theme';
import BaseToast from './BaseToast';

function ErrorToast({ style, props, isVisible }) {
return (
<BaseToast
customToastStyle={style}
isVisible={isVisible}
iconName="error-rectangle"
{...props}
/>
);
}

ErrorToast.propTypes = BaseToast.propTypes;

export default connectStyle('shoutem.ui.ErrorToast')(ErrorToast);
13 changes: 13 additions & 0 deletions components/ToastMessage/components/InfoToast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import { connectStyle } from '@shoutem/theme';
import BaseToast from './BaseToast';

function InfoToast({ style, props, isVisible }) {
return (
<BaseToast customToastStyle={style} isVisible={isVisible} {...props} />
);
}

InfoToast.propTypes = BaseToast.propTypes;

export default connectStyle('shoutem.ui.InfoToast')(InfoToast);
18 changes: 18 additions & 0 deletions components/ToastMessage/components/SuccessToast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import { connectStyle } from '@shoutem/theme';
import BaseToast from './BaseToast';

function SuccessToast({ style, props, isVisible }) {
return (
<BaseToast
customToastStyle={style}
iconName="checkmark-round"
isVisible={isVisible}
{...props}
/>
);
}

SuccessToast.propTypes = BaseToast.propTypes;

export default connectStyle('shoutem.ui.SuccessToast')(SuccessToast);
Loading

0 comments on commit f9bdf33

Please sign in to comment.