From 29dd579360c97823323c4918e7b550ea089d2c39 Mon Sep 17 00:00:00 2001 From: tomislav-arambasic <57353746+tomislav-arambasic@users.noreply.github.com> Date: Mon, 9 May 2022 11:28:28 +0200 Subject: [PATCH 1/6] Enable Android fullscreen Vimeo play (bug fixed) (#716) * Enable Android fullscreen Vimeo play (bug fixed) * Set allowsFullscreenVideo --- components/Video/Video.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/components/Video/Video.js b/components/Video/Video.js index 19f9ddae..ffe14be2 100644 --- a/components/Video/Video.js +++ b/components/Video/Video.js @@ -64,16 +64,10 @@ class Video extends PureComponent { render() { const { width, height, style, poster } = this.props; - // https://github.com/vimeo/player.js/issues/514 - // Vimeo player crashes the app, if played in full screen portrait mode and if user - // tries to navigate back using Android hardware back button. Disableing full screen - // option for Vimeo until their player is fixed. - const isYoutubeVideo = this.sourceReader.isYouTube; - return ( Date: Thu, 19 May 2022 11:39:23 +0200 Subject: [PATCH 2/6] Feature/apply prop types conventions (#709) * Adjust prop type and defaults declaration to match conventions * Re-add NumberInput style PropTypes.shape declaration * Fix ViewPropTypes usage, remove inappropriate defaultProps spread * Apply conventions to YearRangePicker (missed in initial sweep) --- components/ActionSheet/ActionSheet.js | 23 ++-- components/ActionSheet/ActionSheetOption.js | 9 +- components/DateTimePicker.js | 5 +- components/DropDownMenu/DropDownMenu.js | 43 ++++---- components/DropDownMenu/DropDownModal.js | 102 +++++++++--------- components/EmptyStateView.js | 18 ++-- components/FormGroup.js | 4 + components/GridRow.js | 2 +- components/HorizontalPager/HorizontalPager.js | 92 ++++++++-------- components/HorizontalPager/Page.js | 19 ++-- components/Icon/Icon.js | 2 +- components/Image.js | 8 +- components/ImageBackground.js | 8 +- .../ImageGallery/ImageGallery.android.js | 8 ++ components/ImageGallery/ImageGallery.ios.js | 8 ++ components/ImageGallery/ImageGalleryBase.js | 99 +++++++++-------- components/ImageGalleryOverlay.js | 17 +-- components/ImagePreview.js | 22 ++-- .../InlineDropDownMenu/InlineDropDownMenu.js | 43 +++++--- .../InlineDropDownMenuItem.js | 26 +++-- components/InlineGallery.js | 77 +++++++------ components/LinearGradient.js | 10 ++ components/ListView.js | 3 +- components/LoadingContainer.js | 3 +- components/NavigationBar/NavigationBar.js | 31 +++--- components/NumberInput.js | 56 +++++----- components/PageIndicators.js | 36 ++++--- components/ScrollView/ScrollDriverProvider.js | 30 ++++-- components/ScrollView/ScrollView.js | 14 ++- components/SearchField.js | 42 ++++---- components/ShareButton.js | 32 ++++-- components/Spinner.js | 2 +- components/Switch.js | 33 +++--- components/TabMenu/TabMenu.js | 19 ++-- components/TabMenu/TabMenuItem.js | 20 ++-- components/TextInput.js | 4 +- components/Touchable.js | 12 +-- components/TouchableNativeFeedback.js | 16 +-- components/Video/Video.js | 38 +++---- components/View.js | 2 +- components/YearRangePicker/YearRangePicker.js | 39 ++++--- .../YearRangePicker/YearRangePickerButton.js | 20 ++-- .../YearRangePicker/YearRangePickerModal.js | 39 ++++--- .../screens/RestaurantDetails.js | 12 ++- .../RestaurantsApp/screens/Restaurants.js | 17 +-- .../RestaurantsApp/screens/RestaurantsList.js | 12 ++- examples/components/NavigationBars.js | 4 + examples/components/Stage.js | 7 +- html/Html.js | 16 +-- html/components/Gallery.js | 14 ++- html/components/Image.js | 22 ++-- html/components/SimpleHtml.js | 29 +++-- html/elements/A.js | 17 +-- html/elements/Inline.js | 27 +++-- html/elements/Text.js | 6 ++ html/elements/Video.js | 4 +- html/elements/list/Li.js | 2 - html/elements/list/Ol.js | 4 + html/elements/list/Ul.js | 4 + html/elements/list/prefix/Bullet.js | 4 + html/elements/list/prefix/Number.js | 7 +- 61 files changed, 795 insertions(+), 549 deletions(-) diff --git a/components/ActionSheet/ActionSheet.js b/components/ActionSheet/ActionSheet.js index 79532cbf..90ead9f5 100644 --- a/components/ActionSheet/ActionSheet.js +++ b/components/ActionSheet/ActionSheet.js @@ -33,14 +33,6 @@ class ActionSheet extends PureComponent { return null; } - static propTypes = { - style: PropTypes.any, - confirmOptions: PropTypes.arrayOf(optionPropType), - cancelOptions: PropTypes.arrayOf(optionPropType), - active: PropTypes.bool, - onDismiss: PropTypes.func, - }; - constructor(props) { super(props); @@ -187,4 +179,19 @@ class ActionSheet extends PureComponent { } } +ActionSheet.propTypes = { + style: PropTypes.object.isRequired, + active: PropTypes.bool, + cancelOptions: PropTypes.arrayOf(optionPropType), + confirmOptions: PropTypes.arrayOf(optionPropType), + onDismiss: PropTypes.func, +}; + +ActionSheet.defaultProps = { + active: false, + cancelOptions: undefined, + confirmOptions: undefined, + onDismiss: undefined, +}; + export default connectStyle('shoutem.ui.ActionSheet')(ActionSheet); diff --git a/components/ActionSheet/ActionSheetOption.js b/components/ActionSheet/ActionSheetOption.js index 1e884aa5..e89a053b 100644 --- a/components/ActionSheet/ActionSheetOption.js +++ b/components/ActionSheet/ActionSheetOption.js @@ -26,9 +26,14 @@ function ActionSheetOption({ style, option, cancelOption }) { } ActionSheetOption.propTypes = { - style: PropTypes.any, - option: optionPropType, + style: PropTypes.object.isRequired, cancelOption: PropTypes.bool, + option: optionPropType, +}; + +ActionSheetOption.defaultProps = { + option: undefined, + cancelOption: false, }; export default connectStyle('shoutem.ui.ActionSheetOption')(ActionSheetOption); diff --git a/components/DateTimePicker.js b/components/DateTimePicker.js index bde0530a..1757a4f2 100644 --- a/components/DateTimePicker.js +++ b/components/DateTimePicker.js @@ -198,13 +198,14 @@ class DateTimePicker extends PureComponent { } DateTimePicker.propTypes = { + style: PropTypes.object.isRequired, cancelButtonText: PropTypes.string, confirmButtonText: PropTypes.string, is24Hour: PropTypes.bool, mode: PropTypes.oneOf(Object.values(DATEPICKER_MODES)), - onValueChanged: PropTypes.func, textValue: PropTypes.string, value: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)]), + onValueChanged: PropTypes.func, }; DateTimePicker.defaultProps = { @@ -212,7 +213,9 @@ DateTimePicker.defaultProps = { confirmButtonText: 'Confirm', is24Hour: false, mode: 'datetime', + textValue: undefined, value: new Date(), + onValueChanged: undefined, }; const StyledDateTimePicker = connectStyle('shoutem.ui.DateTimePicker')( diff --git a/components/DropDownMenu/DropDownMenu.js b/components/DropDownMenu/DropDownMenu.js index a2b92b27..d0dc0ac2 100644 --- a/components/DropDownMenu/DropDownMenu.js +++ b/components/DropDownMenu/DropDownMenu.js @@ -10,31 +10,8 @@ import { View } from '../View'; import { DropDownModal } from './DropDownModal'; const modalSpecificProps = ['visible', 'onClose']; -const dropDownMenuPropTypes = { - ..._.omit(DropDownModal.propTypes, modalSpecificProps), -}; class DropDownMenu extends PureComponent { - /** - * @see DropDownModal.propTypes - */ - static propTypes = { - /** - * Icon displayed on dropdown menu button - */ - iconName: PropTypes.string, - /** - * Whether the text should be displayed next to dropdown icon or not - */ - showSelectedOption: PropTypes.bool, - ...dropDownMenuPropTypes, - }; - - static defaultProps = { - iconName: 'drop-down', - showSelectedOption: true, - }; - constructor(props) { super(props); @@ -105,6 +82,26 @@ class DropDownMenu extends PureComponent { } } +/** + * @see DropDownModal.propTypes + */ +DropDownMenu.propTypes = { + /** + * Icon displayed on dropdown menu button + */ + iconName: PropTypes.string, + /** + * Whether the text should be displayed next to dropdown icon or not + */ + showSelectedOption: PropTypes.bool, + ..._.omit(DropDownModal.propTypes, modalSpecificProps), +}; + +DropDownMenu.defaultProps = { + iconName: 'drop-down', + showSelectedOption: true, +}; + const StyledDropDownMenu = connectStyle('shoutem.ui.DropDownMenu')( DropDownMenu, ); diff --git a/components/DropDownMenu/DropDownModal.js b/components/DropDownMenu/DropDownModal.js index a5574f80..3b812108 100644 --- a/components/DropDownMenu/DropDownModal.js +++ b/components/DropDownMenu/DropDownModal.js @@ -15,57 +15,6 @@ import { View } from '../View'; const window = Dimensions.get('window'); class DropDownModal extends PureComponent { - static propTypes = { - /** - * Callback that is called when dropdown option is selected - */ - onOptionSelected: PropTypes.func, - /** - * Collection of objects which will be shown as options in DropDownMenu - */ - options: PropTypes.array.isRequired, - /** - * Selected option that will be shown. - */ - selectedOption: PropTypes.any.isRequired, - /** - * Key name that represents option's string value, - * and it will be displayed to the user in the UI - */ - titleProperty: PropTypes.string.isRequired, - /** - * Key name that represents option's value - */ - valueProperty: PropTypes.string.isRequired, - /** - * Number of options shown without scroll. - * Can be set trough DropDown style.visibleOptions. - * Prop definition overrides style. - */ - visibleOptions: PropTypes.number, - /** - * Optional render function, for every item in the list. - * Input parameter should be shaped as one of the items from the - * options object - */ - renderOption: PropTypes.func, - /** - * Visibility flag, controling the modal visibility - */ - visible: PropTypes.bool, - /** - * Callback that is called when modal should be closed - */ - onClose: PropTypes.func, - style: PropTypes.object, - }; - - static defaultProps = { - renderOption: (option, titleProperty) => ( - {option[titleProperty].toUpperCase()} - ), - }; - static DEFAULT_VISIBLE_OPTIONS = 8; constructor(props) { @@ -299,6 +248,57 @@ class DropDownModal extends PureComponent { } } +DropDownModal.propTypes = { + /** + * Collection of objects which will be shown as options in DropDownMenu + */ + options: PropTypes.array.isRequired, + /** + * Selected option that will be shown. + */ + selectedOption: PropTypes.any.isRequired, + style: PropTypes.object.isRequired, + /** + * Key name that represents option's string value, + * and it will be displayed to the user in the UI + */ + titleProperty: PropTypes.string.isRequired, + /** + * Optional render function, for every item in the list. + * Input parameter should be shaped as one of the items from the + * options object + */ + renderOption: PropTypes.func, + /** + * Visibility flag, controling the modal visibility + */ + visible: PropTypes.bool, + /** + * Number of options shown without scroll. + * Can be set trough DropDown style.visibleOptions. + * Prop definition overrides style. + */ + visibleOptions: PropTypes.number, + /** + * Callback that is called when modal should be closed + */ + onClose: PropTypes.func, + /** + * Callback that is called when dropdown option is selected + */ + onOptionSelected: PropTypes.func, +}; + +DropDownModal.defaultProps = { + renderOption: (option, titleProperty) => ( + {option[titleProperty].toUpperCase()} + ), + visible: false, + visibleOptions: undefined, + onClose: undefined, + onOptionSelected: undefined, +}; + const StyledModal = connectStyle('shoutem.ui.DropDownModal')(DropDownModal); export { StyledModal as DropDownModal }; diff --git a/components/EmptyStateView.js b/components/EmptyStateView.js index b203c331..c1193c61 100644 --- a/components/EmptyStateView.js +++ b/components/EmptyStateView.js @@ -8,11 +8,6 @@ import { Subtitle, Text } from './Text'; import { View } from './View'; class EmptyStateView extends PureComponent { - static defaultProps = { - retryButtonTitle: 'TRY AGAIN', - icon: 'error', - }; - constructor(props) { super(props); @@ -54,10 +49,17 @@ class EmptyStateView extends PureComponent { } EmptyStateView.propTypes = { - ...EmptyStateView.propTypes, - onRetry: PropTypes.func, - message: PropTypes.string, icon: PropTypes.string, + message: PropTypes.string, + retryButtonTitle: PropTypes.string, + onRetry: PropTypes.func, +}; + +EmptyStateView.defaultProps = { + icon: 'error', + message: undefined, + retryButtonTitle: 'TRY AGAIN', + onRetry: undefined, }; const StyledView = connectStyle('shoutem.ui.EmptyStateView')(EmptyStateView); diff --git a/components/FormGroup.js b/components/FormGroup.js index bc2c9250..3a58b99f 100644 --- a/components/FormGroup.js +++ b/components/FormGroup.js @@ -13,6 +13,10 @@ FormGroup.propTypes = { ...View.propTypes, }; +FormGroup.defaultProps = { + ...View.defaultProps, +}; + const AnimatedFormGroup = connectAnimation(FormGroup); const StyledFormGroup = connectStyle('shoutem.ui.FormGroup')(AnimatedFormGroup); diff --git a/components/GridRow.js b/components/GridRow.js index 8c028321..b3bbae04 100644 --- a/components/GridRow.js +++ b/components/GridRow.js @@ -35,8 +35,8 @@ class GridRow extends PureComponent { } GridRow.propTypes = { - columns: PropTypes.number.isRequired, ...ViewPropTypes, + columns: PropTypes.number.isRequired, }; /* eslint-disable no-param-reassign */ diff --git a/components/HorizontalPager/HorizontalPager.js b/components/HorizontalPager/HorizontalPager.js index 5e61b290..83f948f1 100644 --- a/components/HorizontalPager/HorizontalPager.js +++ b/components/HorizontalPager/HorizontalPager.js @@ -19,49 +19,6 @@ import { Page } from './Page'; * */ class HorizontalPager extends PureComponent { - static propTypes = { - // Prop defining whether the Pager will bounce back - // when user tries to swipe beyond end of content (iOS only) - bounces: PropTypes.bool, - // Array containing objects (pages) - data: PropTypes.arrayOf(PropTypes.object).isRequired, - // Callback function called when user swipes between pages (images) - // Index of new (selected) page is passed to this callback - onIndexSelected: PropTypes.func, - // Page margin, margin visible between pages, during swipe gesture. - pageMargin: PropTypes.number, - // A function which renders a single page - // renderPage(pageData, pageIndex) - renderPage: PropTypes.func, - // Callback function that can be used to render overlay over pages - // For example page indicators using `PageIndicators` component - // renderOverlay(pageData, pageIndex, layout) - renderOverlay: PropTypes.func, - // Callback function that can be used to define placeholder - // that appears when content is loading - renderPlaceholder: PropTypes.func, - // Initially selected page in gallery - selectedIndex: PropTypes.number, - // Prop that forces enables or disables swiping - scrollEnabled: PropTypes.bool, - // Style prop used to override default (theme) styling - style: PropTypes.object, - // Prop that reduces page size by pageMargin, allowing 'sneak peak' of next page - showNextPage: PropTypes.bool, - // Always render only central (currently loaded) page plus `surroundingPagesToLoad` - // to the left and to the right. If currently rendered page is out of bounds, - // empty `View` (with set dimensions for proper scrolling) will be rendered - // Defaults to 2. - surroundingPagesToLoad: PropTypes.number, - }; - - static defaultProps = { - pageMargin: 0, - selectedIndex: 0, - showNextPage: false, - surroundingPagesToLoad: 2, - }; - constructor(props) { super(props); @@ -312,6 +269,55 @@ class HorizontalPager extends PureComponent { } } +HorizontalPager.propTypes = { + // Array containing objects (pages) + data: PropTypes.arrayOf(PropTypes.object).isRequired, + // Style prop used to override default (theme) styling + style: PropTypes.object.isRequired, + // Prop defining whether the Pager will bounce back + // when user tries to swipe beyond end of content (iOS only) + bounces: PropTypes.bool, + // Page margin, margin visible between pages, during swipe gesture. + pageMargin: PropTypes.number, + // Callback function that can be used to render overlay over pages + // For example page indicators using `PageIndicators` component + // renderOverlay(pageData, pageIndex, layout) + renderOverlay: PropTypes.func, + // A function which renders a single page + // renderPage(pageData, pageIndex) + renderPage: PropTypes.func, + // Callback function that can be used to define placeholder + // that appears when content is loading + renderPlaceholder: PropTypes.func, + // Prop that forces enables or disables swiping + scrollEnabled: PropTypes.bool, + // Initially selected page in gallery + selectedIndex: PropTypes.number, + // Prop that reduces page size by pageMargin, allowing 'sneak peak' of next page + showNextPage: PropTypes.bool, + // Always render only central (currently loaded) page plus `surroundingPagesToLoad` + // to the left and to the right. If currently rendered page is out of bounds, + // empty `View` (with set dimensions for proper scrolling) will be rendered + // Defaults to 2. + surroundingPagesToLoad: PropTypes.number, + // Callback function called when user swipes between pages (images) + // Index of new (selected) page is passed to this callback + onIndexSelected: PropTypes.func, +}; + +HorizontalPager.defaultProps = { + bounces: false, + pageMargin: 0, + renderOverlay: undefined, + renderPage: undefined, + renderPlaceholder: undefined, + scrollEnabled: false, + selectedIndex: 0, + showNextPage: false, + surroundingPagesToLoad: 2, + onIndexSelected: undefined, +}; + const StyledHorizontalPager = connectStyle('shoutem.ui.HorizontalPager')( HorizontalPager, ); diff --git a/components/HorizontalPager/Page.js b/components/HorizontalPager/Page.js index be93dbc6..1bb25e1f 100644 --- a/components/HorizontalPager/Page.js +++ b/components/HorizontalPager/Page.js @@ -8,13 +8,6 @@ import { View } from '../View'; * rendering of pages that are not currently visible. */ export class Page extends Component { - static propTypes = { - isActive: PropTypes.bool.isRequired, - width: PropTypes.number.isRequired, - style: PropTypes.object, - children: PropTypes.node, - }; - shouldComponentUpdate(nextProps) { return nextProps.isActive; } @@ -29,3 +22,15 @@ export class Page extends Component { ); } } + +Page.propTypes = { + isActive: PropTypes.bool.isRequired, + width: PropTypes.number.isRequired, + children: PropTypes.node, + style: PropTypes.object, +}; + +Page.defaultProps = { + children: undefined, + style: {}, +}; diff --git a/components/Icon/Icon.js b/components/Icon/Icon.js index 17be7c50..d7f6e78e 100644 --- a/components/Icon/Icon.js +++ b/components/Icon/Icon.js @@ -28,7 +28,7 @@ function Icon({ name, style, ...otherProps }) { Icon.propTypes = { name: PropTypes.string.isRequired, - style: PropTypes.any, + style: PropTypes.object.isRequired, }; export default connectStyle('shoutem.ui.Icon')(Icon); diff --git a/components/Image.js b/components/Image.js index 952ab04b..b8db5df2 100644 --- a/components/Image.js +++ b/components/Image.js @@ -18,10 +18,6 @@ const isValidSource = source => let externalPropsTransformer = null; class Image extends PureComponent { - static propTypes = { - ...RNImage.propTypes, - }; - /** * Set a shared props transformer. The transformer will * be called on each props change, and it should return @@ -85,6 +81,10 @@ class Image extends PureComponent { } } +Image.propTypes = { + ...RNImage.propTypes, +}; + const AnimatedImage = connectAnimation(Image); const StyledImage = connectStyle('shoutem.ui.Image')(AnimatedImage); export { StyledImage as Image }; diff --git a/components/ImageBackground.js b/components/ImageBackground.js index db768290..d5e90927 100644 --- a/components/ImageBackground.js +++ b/components/ImageBackground.js @@ -18,10 +18,6 @@ const isValidSource = source => let externalPropsTransformer = null; class ImageBackground extends PureComponent { - static propTypes = { - ...RNImageBackground.propTypes, - }; - /** * Set a shared props transformer. The transformer will * be called on each props change, and it should return @@ -85,6 +81,10 @@ class ImageBackground extends PureComponent { } } +ImageBackground.propTypes = { + ...RNImageBackground.propTypes, +}; + const AnimatedImage = connectAnimation(ImageBackground); const StyledImage = connectStyle('shoutem.ui.ImageBackground')(AnimatedImage); export { StyledImage as ImageBackground }; diff --git a/components/ImageGallery/ImageGallery.android.js b/components/ImageGallery/ImageGallery.android.js index 816c7a10..4ec066f8 100644 --- a/components/ImageGallery/ImageGallery.android.js +++ b/components/ImageGallery/ImageGallery.android.js @@ -27,6 +27,14 @@ class ImageGallery extends ImageGalleryBase { } } +ImageGallery.propTypes = { + ...ImageGalleryBase.propTypes, +}; + +ImageGallery.defaultProps = { + ...ImageGalleryBase.defaultProps, +}; + const StyledImageGallery = connectStyle('shoutem.ui.ImageGallery')( ImageGallery, ); diff --git a/components/ImageGallery/ImageGallery.ios.js b/components/ImageGallery/ImageGallery.ios.js index 7c82a4bf..5a739eb5 100644 --- a/components/ImageGallery/ImageGallery.ios.js +++ b/components/ImageGallery/ImageGallery.ios.js @@ -105,6 +105,14 @@ class ImageGallery extends ImageGalleryBase { } } +ImageGallery.propTypes = { + ...ImageGalleryBase.propTypes, +}; + +ImageGallery.defaultProps = { + ...ImageGalleryBase.defaultProps, +}; + const StyledImageGallery = connectStyle('shoutem.ui.ImageGallery')( ImageGallery, ); diff --git a/components/ImageGallery/ImageGalleryBase.js b/components/ImageGallery/ImageGalleryBase.js index 576dfa55..85257393 100644 --- a/components/ImageGallery/ImageGalleryBase.js +++ b/components/ImageGallery/ImageGalleryBase.js @@ -24,48 +24,6 @@ export class ImageGalleryBase extends PureComponent { */ static IMAGE_GALLERY_MODE = IMAGE_GALLERY_MODE; - static propTypes = { - // Array containing objects with gallery data (shape defined below) - data: PropTypes.arrayOf( - PropTypes.shape({ - source: PropTypes.shape({ - uri: PropTypes.string, - }), - description: PropTypes.string, - title: PropTypes.string, - }), - ).isRequired, - // Callback function called when user swipes between pages (images) - // Index of new (selected) page is passed to this callback - onIndexSelected: PropTypes.func, - // Initially selected page in gallery - selectedIndex: PropTypes.number, - // onModeChanged(mode), callback function triggered when user taps on single photo - // Or when user transforms (zooms etc.) image - // Useful for hiding external controls (i.e. navigation bar) - // Mode can be `gallery` or `imagePreview` - onModeChanged: PropTypes.func, - // Style prop used to override default (theme) styling - style: PropTypes.object, - // Renders an overlay over all images - // For example page indicators using the `PageIndicators` component - // renderOverlay(imageData, imageIndex) - renderOverlay: PropTypes.func, - // Renders an overlay over a single image - // For example image gallery overlay using the `ImageGalleryOverlay` component - // renderOverlay(imageData, imageIndex) - renderImageOverlay: PropTypes.func, - // Callback function that can be used to define placeholder - // that appears when content is loading - renderPlaceholder: PropTypes.func, - }; - - static defaultProps = { - selectedIndex: 0, - showNextPage: false, - renderPlaceholder: () => , - }; - constructor(props) { super(props); @@ -159,7 +117,13 @@ export class ImageGalleryBase extends PureComponent { } render() { - const { data, renderOverlay, renderPlaceholder, style } = this.props; + const { + data, + renderOverlay, + renderPlaceholder, + showNextPage, + style, + } = this.props; const { selectedIndex, imageSwitchingEnabled } = this.state; return ( @@ -171,7 +135,7 @@ export class ImageGalleryBase extends PureComponent { renderPage={this.renderPage} bounces pageMargin={style.pageMargin} - showNextPage={false} + showNextPage={showNextPage} renderOverlay={renderOverlay} renderPlaceholder={renderPlaceholder} scrollEnabled={imageSwitchingEnabled} @@ -180,3 +144,50 @@ export class ImageGalleryBase extends PureComponent { ); } } + +ImageGalleryBase.propTypes = { + // Array containing objects with gallery data (shape defined below) + data: PropTypes.arrayOf( + PropTypes.shape({ + description: PropTypes.string, + source: PropTypes.shape({ + uri: PropTypes.string, + }), + title: PropTypes.string, + }), + ).isRequired, + // Style prop used to override default (theme) styling + style: PropTypes.object.isRequired, + // Renders an overlay over a single image + // For example image gallery overlay using the `ImageGalleryOverlay` component + // renderOverlay(imageData, imageIndex) + renderImageOverlay: PropTypes.func, + // Renders an overlay over all images + // For example page indicators using the `PageIndicators` component + // renderOverlay(imageData, imageIndex) + renderOverlay: PropTypes.func, + // Callback function that can be used to define placeholder + // that appears when content is loading + renderPlaceholder: PropTypes.func, + // Initially selected page in gallery + selectedIndex: PropTypes.number, + showNextPage: PropTypes.bool, + // Callback function called when user swipes between pages (images) + // Index of new (selected) page is passed to this callback + onIndexSelected: PropTypes.func, + // onModeChanged(mode), callback function triggered when user taps on single photo + // Or when user transforms (zooms etc.) image + // Useful for hiding external controls (i.e. navigation bar) + // Mode can be `gallery` or `imagePreview` + onModeChanged: PropTypes.func, +}; + +ImageGalleryBase.defaultProps = { + selectedIndex: 0, + showNextPage: false, + renderPlaceholder: () => , + renderImageOverlay: undefined, + renderOverlay: undefined, + onIndexSelected: undefined, + onModeChanged: undefined, +}; diff --git a/components/ImageGalleryOverlay.js b/components/ImageGalleryOverlay.js index c81a284d..3a98dcf7 100644 --- a/components/ImageGalleryOverlay.js +++ b/components/ImageGalleryOverlay.js @@ -17,12 +17,6 @@ const DESCRIPTION_LENGTH_TRIM_LIMIT = 90; * a description of an image. */ class ImageGalleryOverlay extends PureComponent { - static propTypes = { - title: PropTypes.string, - description: PropTypes.string, - style: PropTypes.object, - }; - constructor(props) { super(props); @@ -138,6 +132,17 @@ class ImageGalleryOverlay extends PureComponent { } } +ImageGalleryOverlay.propTypes = { + style: PropTypes.object.isRequired, + description: PropTypes.string, + title: PropTypes.string, +}; + +ImageGalleryOverlay.defaultProps = { + description: undefined, + title: undefined, +}; + const AnimatedOverlay = connectAnimation(ImageGalleryOverlay); const StyledOverlay = connectStyle('shoutem.ui.ImageGalleryOverlay', { container: {}, diff --git a/components/ImagePreview.js b/components/ImagePreview.js index 52713fa3..c5a5fb31 100644 --- a/components/ImagePreview.js +++ b/components/ImagePreview.js @@ -4,17 +4,10 @@ import autoBindReact from 'auto-bind/react'; import PropTypes from 'prop-types'; import { makeZoomable } from '@shoutem/animation'; import { connectStyle } from '@shoutem/theme'; -import { Icon } from './Icon/Icon'; +import Icon from './Icon/Icon'; const ZoomableImage = makeZoomable(Image); -const propTypes = { - width: PropTypes.number, - height: PropTypes.number, - source: Image.propTypes.source, - style: PropTypes.object, -}; - const CLOSE_ICON_NAME = 'clear'; const CLOSE_ICON_SIZE = 25; @@ -90,7 +83,18 @@ class ImagePreview extends PureComponent { } } -ImagePreview.propTypes = propTypes; +ImagePreview.propTypes = { + style: PropTypes.object.isRequired, + height: PropTypes.number, + source: Image.propTypes.source, + width: PropTypes.number, +}; + +ImagePreview.defaultProps = { + height: undefined, + source: undefined, + width: undefined, +}; const StyledImagePreview = connectStyle('shoutem.ui.ImagePreview')( ImagePreview, diff --git a/components/InlineDropDownMenu/InlineDropDownMenu.js b/components/InlineDropDownMenu/InlineDropDownMenu.js index f4ee79c3..8ee96522 100644 --- a/components/InlineDropDownMenu/InlineDropDownMenu.js +++ b/components/InlineDropDownMenu/InlineDropDownMenu.js @@ -1,6 +1,6 @@ import React, { PureComponent } from 'react'; -import autoBindReact from 'auto-bind/react'; import { Animated, ScrollView } from 'react-native'; +import autoBindReact from 'auto-bind/react'; import _ from 'lodash'; import PropTypes from 'prop-types'; import { connectStyle } from '@shoutem/theme'; @@ -18,18 +18,6 @@ const optionShape = PropTypes.shape({ }); class InlineDropDownMenu extends PureComponent { - static propTypes = { - heading: PropTypes.string, - selectedDescriptor: PropTypes.string, - options: PropTypes.arrayOf(optionShape).isRequired, - onOptionSelected: PropTypes.func, - selectedOption: optionShape, - headingStyle: PropTypes.object, - containerStyle: PropTypes.object, - selectedOptionContainerStyle: PropTypes.object, - selectedOptionTextStyle: PropTypes.object, - }; - constructor(props) { super(props); @@ -128,10 +116,7 @@ class InlineDropDownMenu extends PureComponent { {collapsed && ( - + {_.map(options, (item, index) => this.renderOption({ item, index }), )} @@ -142,6 +127,30 @@ class InlineDropDownMenu extends PureComponent { } } +InlineDropDownMenu.propTypes = { + options: PropTypes.arrayOf(optionShape).isRequired, + style: PropTypes.object.isRequired, + containerStyle: PropTypes.object, + heading: PropTypes.string, + headingStyle: PropTypes.object, + selectedDescriptor: PropTypes.string, + selectedOption: optionShape, + selectedOptionContainerStyle: PropTypes.object, + selectedOptionTextStyle: PropTypes.object, + onOptionSelected: PropTypes.func, +}; + +InlineDropDownMenu.defaultProps = { + heading: undefined, + headingStyle: undefined, + containerStyle: undefined, + selectedDescriptor: undefined, + selectedOption: undefined, + selectedOptionContainerStyle: undefined, + selectedOptionTextStyle: undefined, + onOptionSelected: undefined, +}; + const StyledComponent = connectStyle('shoutem.ui.InlineDropDownMenu')( InlineDropDownMenu, ); diff --git a/components/InlineDropDownMenu/InlineDropDownMenuItem.js b/components/InlineDropDownMenu/InlineDropDownMenuItem.js index 21327a9e..79206942 100644 --- a/components/InlineDropDownMenu/InlineDropDownMenuItem.js +++ b/components/InlineDropDownMenu/InlineDropDownMenuItem.js @@ -1,7 +1,6 @@ import React, { PureComponent } from 'react'; import { Animated, Dimensions, Pressable } from 'react-native'; import autoBindReact from 'auto-bind/react'; -import _ from 'lodash'; import PropTypes from 'prop-types'; import { connectStyle } from '@shoutem/theme'; import { Text } from '../Text'; @@ -10,14 +9,6 @@ const window = Dimensions.get('window'); const AnimatedPressable = Animated.createAnimatedComponent(Pressable); class InlineDropDownMenuItem extends PureComponent { - static propTypes = { - item: PropTypes.object, - index: PropTypes.number, - selectedDescriptor: PropTypes.string, - onItemPressed: PropTypes.func, - isSelected: PropTypes.bool, - }; - constructor(props) { super(props); @@ -76,6 +67,23 @@ class InlineDropDownMenuItem extends PureComponent { } } +InlineDropDownMenuItem.propTypes = { + style: PropTypes.isRequired, + index: PropTypes.number, + isSelected: PropTypes.bool, + item: PropTypes.object, + selectedDescriptor: PropTypes.string, + onItemPressed: PropTypes.func, +}; + +InlineDropDownMenuItem.defaultProps = { + index: undefined, + isSelected: false, + item: undefined, + selectedDescriptor: undefined, + onItemPressed: undefined, +}; + const StyledComponent = connectStyle('shoutem.ui.InlineDropDownMenuItem')( InlineDropDownMenuItem, ); diff --git a/components/InlineGallery.js b/components/InlineGallery.js index 4d5daed0..2dfd516d 100644 --- a/components/InlineGallery.js +++ b/components/InlineGallery.js @@ -10,48 +10,16 @@ import { TouchableOpacity } from './TouchableOpacity'; import { View } from './View'; class InlineGallery extends PureComponent { - static propTypes = { - // Array containing objects with image data (shape defined below) - data: PropTypes.arrayOf( - PropTypes.shape({ - source: PropTypes.shape({ - uri: PropTypes.string, - }), - }), - ).isRequired, - // Callback function called when user taps on single item (image) in gallery - onPress: PropTypes.func, - // Callback function called when user swipes between pages (images) - // Index of new (selected) page is passed to this callback - onIndexSelected: PropTypes.func, - // Initially selected page in gallery - selectedIndex: PropTypes.number, - // Style, applied to Image component - style: PropTypes.object, - // Prop that reduces page size by pageMargin, allowing 'sneak peak' of next page - // Defaults to false - showNextPage: PropTypes.bool, - // Callback function that can be used to render overlay over pages - // For example page indicators using `PageIndicators` component - // renderOverlay(imageData, imageIndex) - renderOverlay: PropTypes.func, - // Callback function that can be used to define placeholder - // that appears when content is loading - renderPlaceholder: PropTypes.func, - }; - - static defaultProps = { - renderPlaceholder: () => , - }; - constructor(props) { super(props); autoBindReact(this); + const { showNextPage } = props; + this.state = { selectedIndex: 0, - showNextPage: this.props.showNextPage || false, + showNextPage, }; } @@ -125,6 +93,45 @@ class InlineGallery extends PureComponent { } } +InlineGallery.propTypes = { + // Array containing objects with image data (shape defined below) + data: PropTypes.arrayOf( + PropTypes.shape({ + source: PropTypes.shape({ + uri: PropTypes.string, + }), + }), + ).isRequired, + // Style, applied to Image component + style: PropTypes.object.isRequired, + // Callback function that can be used to render overlay over pages + // For example page indicators using `PageIndicators` component + // renderOverlay(imageData, imageIndex) + renderOverlay: PropTypes.func, + // Callback function that can be used to define placeholder + // that appears when content is loading + renderPlaceholder: PropTypes.func, + // Initially selected page in gallery + selectedIndex: PropTypes.number, + // Prop that reduces page size by pageMargin, allowing 'sneak peak' of next page + // Defaults to false + showNextPage: PropTypes.bool, + // Callback function called when user swipes between pages (images) + // Index of new (selected) page is passed to this callback + onIndexSelected: PropTypes.func, + // Callback function called when user taps on single item (image) in gallery + onPress: PropTypes.func, +}; + +InlineGallery.defaultProps = { + renderPlaceholder: () => , + renderOverlay: undefined, + selectedIndex: undefined, + showNextPage: false, + onIndexSelected: undefined, + onPress: undefined, +}; + const StyledInlineGallery = connectStyle('shoutem.ui.InlineGallery')( InlineGallery, ); diff --git a/components/LinearGradient.js b/components/LinearGradient.js index 41f17884..23c5b1cb 100644 --- a/components/LinearGradient.js +++ b/components/LinearGradient.js @@ -1,6 +1,7 @@ import React, { PureComponent } from 'react'; import RNLinearGradient from 'react-native-linear-gradient'; import _ from 'lodash'; +import PropTypes from 'prop-types'; import { connectAnimation } from '@shoutem/animation'; import { connectStyle } from '@shoutem/theme'; @@ -24,6 +25,15 @@ class LinearGradient extends PureComponent { } } +LinearGradient.propTypes = { + style: PropTypes.object.isRequired, + children: PropTypes.node, +}; + +LinearGradient.defaultProps = { + children: undefined, +}; + const AnimatedLinearGradient = connectAnimation(LinearGradient); const StyledLinearGradient = connectStyle('shoutem.ui.LinearGradient')( AnimatedLinearGradient, diff --git a/components/ListView.js b/components/ListView.js index 08fdd3ff..8cc9154e 100644 --- a/components/ListView.js +++ b/components/ListView.js @@ -346,6 +346,7 @@ class ListView extends PureComponent { } ListView.propTypes = { + style: PropTypes.object.isRequired, autoHideHeader: PropTypes.bool, contentContainerStyle: PropTypes.object, data: PropTypes.array, @@ -363,7 +364,6 @@ ListView.propTypes = { renderSectionHeader: PropTypes.func, scrollDriver: PropTypes.object, sections: PropTypes.array, - style: PropTypes.object, onLoadMore: PropTypes.func, onLoadMoreThreshold: PropTypes.number, onRefresh: PropTypes.func, @@ -387,7 +387,6 @@ ListView.defaultProps = { renderSectionHeader: undefined, scrollDriver: undefined, sections: undefined, - style: {}, onLoadMore: undefined, onLoadMoreThreshold: 0.5, onRefresh: undefined, diff --git a/components/LoadingContainer.js b/components/LoadingContainer.js index 885af98c..eabc7723 100644 --- a/components/LoadingContainer.js +++ b/components/LoadingContainer.js @@ -55,6 +55,7 @@ function LoadingContainer({ } LoadingContainer.propTypes = { + style: PropTypes.object.isRequired, animation: PropTypes.object, animationScale: PropTypes.number, children: PropTypes.oneOfType([ @@ -63,7 +64,6 @@ LoadingContainer.propTypes = { PropTypes.node, ]), loading: PropTypes.bool, - style: PropTypes.object, }; LoadingContainer.defaultProps = { @@ -71,7 +71,6 @@ LoadingContainer.defaultProps = { children: undefined, animation: animations.loadingDots, loading: false, - style: {}, }; const StyledLoadingContainer = connectStyle('shoutem.ui.LoadingContainer')( diff --git a/components/NavigationBar/NavigationBar.js b/components/NavigationBar/NavigationBar.js index b46a606f..68745faf 100644 --- a/components/NavigationBar/NavigationBar.js +++ b/components/NavigationBar/NavigationBar.js @@ -20,19 +20,6 @@ function getBackgroundColor(style) { // eslint-disable-next-line react/prefer-stateless-function class NavigationBar extends PureComponent { - static propTypes = { - leftComponent: PropTypes.node, - centerComponent: PropTypes.node, - rightComponent: PropTypes.node, - style: PropTypes.object, - id: PropTypes.string, - statusBarColor: PropTypes.string, - }; - - static defaultProps = { - id: 'default', - }; - setStatusBarStyle(backgroundColor) { function chooseBarStyle(bgColor) { return color(bgColor).isDark() ? 'light-content' : 'default'; @@ -100,6 +87,24 @@ class NavigationBar extends PureComponent { } } +NavigationBar.propTypes = { + style: PropTypes.object.isRequired, + centerComponent: PropTypes.node, + id: PropTypes.string, + leftComponent: PropTypes.node, + rightComponent: PropTypes.node, + // eslint-disable-next-line react/no-unused-prop-types + statusBarColor: PropTypes.string, +}; + +NavigationBar.defaultProps = { + id: 'default', + leftComponent: undefined, + centerComponent: undefined, + rightComponent: undefined, + statusBarColor: undefined, +}; + const AnimatedNavigationBar = connectAnimation(composeChildren(NavigationBar)); const StyledNavigationBar = connectStyle('shoutem.ui.NavigationBar')( AnimatedNavigationBar, diff --git a/components/NumberInput.js b/components/NumberInput.js index e4ada23a..ed3363e6 100644 --- a/components/NumberInput.js +++ b/components/NumberInput.js @@ -22,28 +22,6 @@ import { View } from './View'; * focus and blur events. */ class NumberInput extends PureComponent { - static propTypes = { - ...TextInput.propTypes, - // Maximum allowed value - max: PropTypes.number, - // Minimum allowed value - min: PropTypes.number, - // Called when the user changes the value by inputting it directly or with buttons - onChange: PropTypes.func.isRequired, - // Step used to increase or decrease value with corresponding buttons - step: PropTypes.number, - // Styles for component parts - style: PropTypes.shape({ - button: PropTypes.object, - container: PropTypes.object, - icon: PropTypes.object, - input: PropTypes.object, - inputContainer: PropTypes.object, - }), - // Value of the input - can be empty - value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - }; - constructor(props) { super(props); @@ -57,13 +35,13 @@ class NumberInput extends PureComponent { } decreaseValue() { - const { step = 1, value = 0 } = this.props; + const { step, value } = this.props; this.updateValue(value - step); } increaseValue() { - const { step = 1, value = 0 } = this.props; + const { step, value } = this.props; this.updateValue(value + step); } @@ -113,6 +91,36 @@ class NumberInput extends PureComponent { } } +NumberInput.propTypes = { + ...TextInput.propTypes, + // Styles for component parts + style: PropTypes.shape({ + button: PropTypes.object, + container: PropTypes.object, + icon: PropTypes.object, + input: PropTypes.object, + inputContainer: PropTypes.object, + }).isRequired, + // Called when the user changes the value by inputting it directly or with buttons + onChange: PropTypes.func.isRequired, + // Maximum allowed value + max: PropTypes.number, + // Minimum allowed value + min: PropTypes.number, + // Step used to increase or decrease value with corresponding buttons + step: PropTypes.number, + // Value of the input - can be empty + value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), +}; + +NumberInput.defaultProps = { + ...TextInput.defaultProps, + max: undefined, + min: undefined, + step: 1, + value: 0, +}; + const AnimatedNumberInput = connectAnimation(NumberInput); const StyledNumberInput = connectStyle('shoutem.ui.NumberInput')( AnimatedNumberInput, diff --git a/components/PageIndicators.js b/components/PageIndicators.js index c66b4cde..5969fcaf 100644 --- a/components/PageIndicators.js +++ b/components/PageIndicators.js @@ -8,23 +8,6 @@ import { View } from './View'; * Renders Page indicators (dots) */ class PageIndicators extends PureComponent { - static propTypes = { - // ActiveIndex: number defining which page indicator will be rendered as active (selected) - activeIndex: PropTypes.number, - // Count: number defining how many page indicators will be rendered - count: PropTypes.number, - // maxCount defining highest number of page indicators that can be rendered - // If `count` is higher than `maxCount`, then `maxCount` number of indicators - // will be rendered. Defaults to 10 - maxCount: PropTypes.number, - // Style prop used to override default (theme) styling - style: PropTypes.object, - }; - - static defaultProps = { - maxCount: 10, - }; - constructor(props) { super(props); @@ -73,6 +56,25 @@ class PageIndicators extends PureComponent { } } +PageIndicators.propTypes = { + // Style prop used to override default (theme) styling + style: PropTypes.object.isRequired, + // ActiveIndex: number defining which page indicator will be rendered as active (selected) + activeIndex: PropTypes.number, + // Count: number defining how many page indicators will be rendered + count: PropTypes.number, + // maxCount defining highest number of page indicators that can be rendered + // If `count` is higher than `maxCount`, then `maxCount` number of indicators + // will be rendered. Defaults to 10 + maxCount: PropTypes.number, +}; + +PageIndicators.defaultProps = { + activeIndex: undefined, + count: undefined, + maxCount: 10, +}; + const StyledPageIndicators = connectStyle('shoutem.ui.PageIndicators')( PageIndicators, ); diff --git a/components/ScrollView/ScrollDriverProvider.js b/components/ScrollView/ScrollDriverProvider.js index 42d9b17c..fa0e4a69 100644 --- a/components/ScrollView/ScrollDriverProvider.js +++ b/components/ScrollView/ScrollDriverProvider.js @@ -19,16 +19,6 @@ export class ScrollDriverProvider extends PureComponent { animationDriver: DriverShape, }; - static propTypes = { - children: PropTypes.node, - driver: DriverShape, - // Used to propagate animation driver changes to components who aren't - // children of ScrollDriver, recieves driver as argument. - // TODO: Rewrite for new context API. - onAnimationDriverChange: PropTypes.func, - onScroll: PropTypes.func, - }; - constructor(props, context) { super(props, context); @@ -87,3 +77,23 @@ export class ScrollDriverProvider extends PureComponent { return children && Children.only(children); } } + +// We disable this eslint rule because the props are being utilized indirectly +// through componentDidUpdate's usage of setupAnimationDriver +/* eslint-disable react/no-unused-prop-types */ +ScrollDriverProvider.propTypes = { + children: PropTypes.node, + driver: DriverShape, + // Used to propagate animation driver changes to components that aren't + // children of ScrollDriver, recieves driver as argument. + // TODO: Rewrite for new context API. + onAnimationDriverChange: PropTypes.func, + onScroll: PropTypes.func, +}; + +ScrollDriverProvider.defaultProps = { + children: undefined, + driver: undefined, + onAnimationDriverChange: undefined, + onScroll: undefined, +}; diff --git a/components/ScrollView/ScrollView.js b/components/ScrollView/ScrollView.js index 6dacf11a..f4e92562 100644 --- a/components/ScrollView/ScrollView.js +++ b/components/ScrollView/ScrollView.js @@ -12,11 +12,6 @@ const isTabBarOnScreen = true; const IPHONE_X_HOME_INDICATOR_PADDING = isTabBarOnScreen ? 0 : 34; class ScrollView extends PureComponent { - static propTypes = { - ...Animated.ScrollView.propTypes, - primary: PropTypes.bool, - }; - static contextTypes = { animationDriver: DriverShape, driverProvider: PropTypes.object, @@ -100,6 +95,15 @@ class ScrollView extends PureComponent { } } +ScrollView.propTypes = { + ...Animated.ScrollView.propTypes, + primary: PropTypes.bool, +}; + +ScrollView.defaultProps = { + primary: false, +}; + const StyledScrollView = connectStyle('shoutem.ui.ScrollView')(ScrollView); function getRNScrollViewComponent(context) { diff --git a/components/SearchField.js b/components/SearchField.js index ff71871b..03db55e9 100644 --- a/components/SearchField.js +++ b/components/SearchField.js @@ -14,8 +14,8 @@ const ClearButton = ({ style, onPress }) => ( ); ClearButton.propTypes = { - style: PropTypes.object, - onPress: PropTypes.func, + style: PropTypes.object.isRequired, + onPress: PropTypes.func.isRequired, }; /** @@ -24,22 +24,6 @@ ClearButton.propTypes = { * */ class SearchField extends PureComponent { - static propTypes = { - // A placeholder for input when no value is entered - placeholder: PropTypes.string, - // Called with the new value on text change - onChangeText: PropTypes.func, - // Styles for container and search icon - style: PropTypes.shape({ - clearIcon: PropTypes.object, - container: PropTypes.object, - input: PropTypes.object, - searchIcon: PropTypes.object, - }), - // Value to render as text in search input - value: PropTypes.string, - }; - render() { const { onChangeText, @@ -72,6 +56,28 @@ class SearchField extends PureComponent { } } +SearchField.propTypes = { + // Styles for container and search icon + style: PropTypes.shape({ + clearIcon: PropTypes.object, + container: PropTypes.object, + input: PropTypes.object, + searchIcon: PropTypes.object, + }).isRequired, + // A placeholder for input when no value is entered + placeholder: PropTypes.string, + // Value to render as text in search input + value: PropTypes.string, + // Called with the new value on text change + onChangeText: PropTypes.func, +}; + +SearchField.defaultProps = { + placeholder: undefined, + value: undefined, + onChangeText: undefined, +}; + const AnimatedSearchField = connectAnimation(SearchField); const StyledSearchField = connectStyle('shoutem.ui.SearchField')( AnimatedSearchField, diff --git a/components/ShareButton.js b/components/ShareButton.js index e93a3561..b1b9fcee 100644 --- a/components/ShareButton.js +++ b/components/ShareButton.js @@ -15,17 +15,6 @@ import { Icon } from './Icon'; * or animation. */ class ShareButton extends PureComponent { - static propTypes = { - // Animation name for share icon - animationName: PropTypes.string, - // Message to share - message: PropTypes.string, - // Title - title: PropTypes.string, - // Url to share - url: PropTypes.string, - }; - constructor(props) { super(props); @@ -59,6 +48,27 @@ class ShareButton extends PureComponent { } } +ShareButton.propTypes = { + // Animation name for share icon + animationName: PropTypes.string, + // Additional props for Icon component + iconProps: PropTypes.object, + // Message to share + message: PropTypes.string, + // Title + title: PropTypes.string, + // Url to share + url: PropTypes.string, +}; + +ShareButton.defaultProps = { + animationName: undefined, + iconProps: undefined, + message: undefined, + title: undefined, + url: undefined, +}; + const StyledShareButton = connectStyle( 'shoutem.ui.ShareButton', undefined, diff --git a/components/Spinner.js b/components/Spinner.js index da6af763..4ce91842 100644 --- a/components/Spinner.js +++ b/components/Spinner.js @@ -20,7 +20,7 @@ class Spinner extends PureComponent { } Spinner.propTypes = { - style: PropTypes.object, + style: PropTypes.object.isRequired, }; const StyledSpinner = connectStyle('shoutem.ui.Spinner', { diff --git a/components/Switch.js b/components/Switch.js index acafc77a..1f18b85b 100644 --- a/components/Switch.js +++ b/components/Switch.js @@ -7,20 +7,6 @@ import { connectStyle } from '@shoutem/theme'; import { View } from './View'; class Switch extends PureComponent { - static propTypes = { - // True when switch is on, false otherwise - value: PropTypes.bool, - // Called when switch is toggled on and off - onValueChange: PropTypes.func, - // Styles for the container and underlying thumb - style: PropTypes.shape({ - // Container style - container: PropTypes.object, - // Thumb style - thumb: PropTypes.object, - }), - }; - constructor(props) { super(props); @@ -76,6 +62,25 @@ class Switch extends PureComponent { } } +Switch.propTypes = { + // Styles for the container and underlying thumb + style: PropTypes.shape({ + // Container style + container: PropTypes.object, + // Thumb style + thumb: PropTypes.object, + }).isRequired, + // True when switch is on, false otherwise + value: PropTypes.bool, + // Called when switch is toggled on and off + onValueChange: PropTypes.func, +}; + +Switch.defaultProps = { + value: false, + onValueChange: undefined, +}; + const AnimatedSwitch = connectAnimation(Switch); const StyledSwitch = connectStyle('shoutem.ui.Switch')(AnimatedSwitch); diff --git a/components/TabMenu/TabMenu.js b/components/TabMenu/TabMenu.js index a4246677..9dbc8dce 100644 --- a/components/TabMenu/TabMenu.js +++ b/components/TabMenu/TabMenu.js @@ -8,13 +8,6 @@ import { optionShape } from './const'; import { TabMenuItem } from './TabMenuItem'; class TabMenu extends PureComponent { - static propTypes = { - options: PropTypes.arrayOf(optionShape).isRequired, - onOptionSelected: PropTypes.func, - selectedOption: optionShape, - style: PropTypes.object, - }; - constructor(props) { super(props); @@ -59,6 +52,18 @@ class TabMenu extends PureComponent { } } +TabMenu.propTypes = { + options: PropTypes.arrayOf(optionShape).isRequired, + style: PropTypes.object.isRequired, + selectedOption: optionShape, + onOptionSelected: PropTypes.func, +}; + +TabMenu.defaultProps = { + selectedOption: undefined, + onOptionSelected: undefined, +}; + const StyledTabMenu = connectStyle('shoutem.ui.TabMenu')(TabMenu); export { StyledTabMenu as TabMenu }; diff --git a/components/TabMenu/TabMenuItem.js b/components/TabMenu/TabMenuItem.js index b9bad158..6a9e5fde 100644 --- a/components/TabMenu/TabMenuItem.js +++ b/components/TabMenu/TabMenuItem.js @@ -10,13 +10,6 @@ import { View } from '../View'; import { optionShape } from './const'; class TabMenuItem extends PureComponent { - static propTypes = { - item: optionShape, - onItemPressed: PropTypes.any, - isSelected: PropTypes.bool, - style: PropTypes.object, - }; - constructor(props) { super(props); @@ -63,6 +56,19 @@ class TabMenuItem extends PureComponent { } } +TabMenuItem.propTypes = { + style: PropTypes.object.isRequired, + isSelected: PropTypes.bool, + item: optionShape, + onItemPressed: PropTypes.func, +}; + +TabMenuItem.defaultProps = { + isSelected: false, + item: undefined, + onItemPressed: undefined, +}; + const StyledTabMenuItem = connectStyle('shoutem.ui.TabMenuItem')(TabMenuItem); export { StyledTabMenuItem as TabMenuItem }; diff --git a/components/TextInput.js b/components/TextInput.js index f6fca3e8..4d115888 100644 --- a/components/TextInput.js +++ b/components/TextInput.js @@ -90,12 +90,14 @@ class TextInput extends PureComponent { TextInput.propTypes = { ...RNTextInput.propTypes, + style: PropTypes.object.isRequired, animate: PropTypes.bool, - style: PropTypes.object, + errorMessage: PropTypes.string, }; TextInput.defaultProps = { animate: true, + errorMessage: undefined, }; const AnimatedTextInput = connectAnimation(TextInput); diff --git a/components/Touchable.js b/components/Touchable.js index 3558c2d0..de22935f 100644 --- a/components/Touchable.js +++ b/components/Touchable.js @@ -14,12 +14,6 @@ import { View } from './View'; * Android. */ class Touchable extends PureComponent { - static propTypes = { - ...TouchableOpacity.propTypes, - ...TouchableNativeFeedback.propTypes, - style: PropTypes.object, - }; - render() { const { props } = this; const style = { ...props.style }; @@ -53,6 +47,12 @@ class Touchable extends PureComponent { } } +Touchable.propTypes = { + ...TouchableOpacity.propTypes, + ...TouchableNativeFeedback.propTypes, + style: PropTypes.object.isRequired, +}; + const StyledTouchable = connectStyle('shoutem.ui.Touchable', { touchableNativeFeedback: {}, touchableOpacity: {}, diff --git a/components/TouchableNativeFeedback.js b/components/TouchableNativeFeedback.js index f646f075..7ff49aaa 100644 --- a/components/TouchableNativeFeedback.js +++ b/components/TouchableNativeFeedback.js @@ -4,14 +4,6 @@ import PropTypes from 'prop-types'; import { connectStyle } from '@shoutem/theme'; class TouchableNativeFeedback extends PureComponent { - static propTypes = { - ...RNTouchableNativeFeedback.propTypes, - style: PropTypes.shape({ - background: PropTypes.object, - useForeground: PropTypes.bool, - }), - }; - render() { const { props } = this; // Remove the props that are not valid @@ -35,6 +27,14 @@ class TouchableNativeFeedback extends PureComponent { } } +TouchableNativeFeedback.propTypes = { + ...RNTouchableNativeFeedback.propTypes, + style: PropTypes.shape({ + background: PropTypes.object, + useForeground: PropTypes.bool, + }).isRequired, +}; + const StyledTouchableNativeFeedback = connectStyle( 'shoutem.ui.TouchableNativeFeedback', )(TouchableNativeFeedback); diff --git a/components/Video/Video.js b/components/Video/Video.js index ffe14be2..4f48f068 100644 --- a/components/Video/Video.js +++ b/components/Video/Video.js @@ -36,24 +36,6 @@ function getSource(sourceReader, poster) { * @returns {*} */ class Video extends PureComponent { - static propTypes = { - width: PropTypes.number, - height: PropTypes.number, - // `playerParams` currently only works for Youtube - playerParams: PropTypes.object, - source: PropTypes.shape({ - uri: PropTypes.string, - }), - style: PropTypes.object, - poster: PropTypes.string, - }; - - static defaultProps = { - playerParams: { - showinfo: 0, - }, - }; - constructor(props) { super(props); @@ -79,6 +61,26 @@ class Video extends PureComponent { } } +Video.propTypes = { + style: PropTypes.object.isRequired, + height: PropTypes.number, + // `playerParams` currently only works for Youtube + playerParams: PropTypes.object, + poster: PropTypes.string, + source: PropTypes.shape({ + uri: PropTypes.string, + }), + width: PropTypes.number, +}; + +Video.defaultProps = { + width: undefined, + height: undefined, + playerParams: { showinfo: 0 }, + source: undefined, + poster: undefined, +}; + const AnimatedVideo = connectAnimation(Video); const StyledVideo = connectStyle('shoutem.ui.Video')(AnimatedVideo); diff --git a/components/View.js b/components/View.js index 0e5fea69..2e5ebcaf 100644 --- a/components/View.js +++ b/components/View.js @@ -33,7 +33,7 @@ class View extends PureComponent { View.propTypes = { ...ViewPropTypes, - style: PropTypes.object, + style: PropTypes.object.isRequired, }; const AnimatedView = connectAnimation(View); diff --git a/components/YearRangePicker/YearRangePicker.js b/components/YearRangePicker/YearRangePicker.js index ae5d0e9c..468b2975 100644 --- a/components/YearRangePicker/YearRangePicker.js +++ b/components/YearRangePicker/YearRangePicker.js @@ -25,22 +25,6 @@ function formatButtonTooltip(props) { } class YearRangePicker extends PureComponent { - static propTypes = { - onRangeConfirmed: PropTypes.func, - onReset: PropTypes.func, - resetButtonTitle: PropTypes.string, - confirmButtonTitle: PropTypes.string, - selectedYears: PropTypes.arrayOf(PropTypes.number), - rangeStart: PropTypes.number, - rangeEnd: PropTypes.number, - buttonPlaceholder: PropTypes.string, - }; - - static defaultProps = { - selectedYears: [], - buttonPlaceholder: 'Year', - }; - constructor(props) { super(props); @@ -48,7 +32,6 @@ class YearRangePicker extends PureComponent { this.state = { collapsed: false, - selectedYears: props.selectedYears, buttonTooltip: formatButtonTooltip(props), }; } @@ -108,4 +91,26 @@ class YearRangePicker extends PureComponent { } } +YearRangePicker.propTypes = { + // Disabling as this prop is used in the formatButtonTooltip function. + // eslint-disable-next-line react/no-unused-prop-types + buttonPlaceholder: PropTypes.string, + confirmButtonTitle: PropTypes.string, + rangeEnd: PropTypes.number, + rangeStart: PropTypes.number, + resetButtonTitle: PropTypes.string, + selectedYears: PropTypes.arrayOf(PropTypes.number), + onRangeConfirmed: PropTypes.func, +}; + +YearRangePicker.defaultProps = { + buttonPlaceholder: 'Year', + confirmButtonTitle: undefined, + rangeEnd: undefined, + rangeStart: undefined, + resetButtonTitle: undefined, + selectedYears: [], + onRangeConfirmed: undefined, +}; + export default connectStyle('shoutem.ui.YearRangePicker')(YearRangePicker); diff --git a/components/YearRangePicker/YearRangePickerButton.js b/components/YearRangePicker/YearRangePickerButton.js index 7517c6fa..7c3b0227 100644 --- a/components/YearRangePicker/YearRangePickerButton.js +++ b/components/YearRangePicker/YearRangePickerButton.js @@ -10,13 +10,6 @@ import { TouchableOpacity } from '../TouchableOpacity'; const AnimatedIcon = Animated.createAnimatedComponent(Icon); class YearRangePickerButton extends PureComponent { - static propTypes = { - onPress: PropTypes.func, - tooltip: PropTypes.string, - collapsed: PropTypes.bool, - style: PropTypes.any, - }; - constructor(props) { super(props); @@ -65,6 +58,19 @@ class YearRangePickerButton extends PureComponent { } } +YearRangePickerButton.propTypes = { + style: PropTypes.object.isRequired, + collapsed: PropTypes.bool, + tooltip: PropTypes.string, + onPress: PropTypes.func, +}; + +YearRangePickerButton.defaultProps = { + collapsed: undefined, + tooltip: undefined, + onPress: undefined, +}; + export default connectStyle('shoutem.ui.YearRangePickerButton')( YearRangePickerButton, ); diff --git a/components/YearRangePicker/YearRangePickerModal.js b/components/YearRangePicker/YearRangePickerModal.js index 41e4a1c9..d72600af 100644 --- a/components/YearRangePicker/YearRangePickerModal.js +++ b/components/YearRangePicker/YearRangePickerModal.js @@ -42,22 +42,6 @@ function resolveRangeTooltip(visibleYears) { } class YearRangePickerModal extends PureComponent { - static propTypes = { - onRangeConfirmed: PropTypes.func, - onDismiss: PropTypes.func, - resetButtonTitle: PropTypes.string, - confirmButtonTitle: PropTypes.string, - selectedYears: PropTypes.arrayOf(PropTypes.number), - rangeStart: PropTypes.number, - rangeEnd: PropTypes.number, - visible: PropTypes.bool, - style: PropTypes.any, - }; - - static defaultProps = { - selectedYears: [], - }; - constructor(props) { super(props); @@ -283,6 +267,29 @@ class YearRangePickerModal extends PureComponent { } } +YearRangePickerModal.propTypes = { + style: PropTypes.object.isRequired, + confirmButtonTitle: PropTypes.string, + rangeEnd: PropTypes.number, + rangeStart: PropTypes.number, + resetButtonTitle: PropTypes.string, + selectedYears: PropTypes.arrayOf(PropTypes.number), + visible: PropTypes.bool, + onDismiss: PropTypes.func, + onRangeConfirmed: PropTypes.func, +}; + +YearRangePickerModal.defaultProps = { + confirmButtonTitle: undefined, + rangeEnd: undefined, + rangeStart: undefined, + resetButtonTitle: undefined, + selectedYears: [], + visible: false, + onDismiss: undefined, + onRangeConfirmed: undefined, +}; + export default connectStyle('shoutem.ui.YearRangePickerModal')( YearRangePickerModal, ); diff --git a/examples/RestaurantsApp/screens/RestaurantDetails.js b/examples/RestaurantsApp/screens/RestaurantDetails.js index 2235d53d..d041adb7 100644 --- a/examples/RestaurantsApp/screens/RestaurantDetails.js +++ b/examples/RestaurantsApp/screens/RestaurantDetails.js @@ -16,10 +16,6 @@ import { import { NavigationBar } from '@shoutem/ui/navigation'; export default class RestaurantDetails extends PureComponent { - static propTypes = { - restaurant: PropTypes.object, - }; - render() { const { restaurant } = this.props; @@ -86,3 +82,11 @@ export default class RestaurantDetails extends PureComponent { ); } } + +RestaurantDetails.propTypes = { + restaurant: PropTypes.object, +}; + +RestaurantDetails.defaultProps = { + restaurant: undefined, +}; diff --git a/examples/RestaurantsApp/screens/Restaurants.js b/examples/RestaurantsApp/screens/Restaurants.js index 22dc05a8..a63ecbd9 100644 --- a/examples/RestaurantsApp/screens/Restaurants.js +++ b/examples/RestaurantsApp/screens/Restaurants.js @@ -8,12 +8,6 @@ import RestaurantDetails from './RestaurantDetails'; import RestaurantsList from './RestaurantsList'; class Restaurants extends PureComponent { - static propTypes = { - onNavigateBack: PropTypes.func.isRequired, - navigationState: PropTypes.object, - scene: PropTypes.object, - }; - constructor(props) { super(props); @@ -49,6 +43,17 @@ class Restaurants extends PureComponent { } } +Restaurants.propTypes = { + onNavigateBack: PropTypes.func.isRequired, + navigationState: PropTypes.object, + scene: PropTypes.object, +}; + +Restaurants.defaultProps = { + navigationState: undefined, + scene: undefined, +}; + export default connect(state => ({ navigationState: state.navigationState }), { onNavigateBack: navigatePop, })(Restaurants); diff --git a/examples/RestaurantsApp/screens/RestaurantsList.js b/examples/RestaurantsApp/screens/RestaurantsList.js index 1316dcc0..d852890a 100644 --- a/examples/RestaurantsApp/screens/RestaurantsList.js +++ b/examples/RestaurantsApp/screens/RestaurantsList.js @@ -18,10 +18,6 @@ import { navigatePush } from '../redux'; const restaurants = require('../assets/data/restaurants.json'); class RestaurantsList extends PureComponent { - static propTypes = { - onButtonPress: PropTypes.func, - }; - constructor(props) { super(props); @@ -62,6 +58,14 @@ class RestaurantsList extends PureComponent { } } +RestaurantsList.propTypes = { + onButtonPress: PropTypes.func, +}; + +RestaurantsList.defaultProps = { + onButtonPress: undefined, +}; + const mapDispatchToProps = dispatch => ({ onButtonPress: restaurant => { dispatch( diff --git a/examples/components/NavigationBars.js b/examples/components/NavigationBars.js index 88b26da7..7767e14d 100644 --- a/examples/components/NavigationBars.js +++ b/examples/components/NavigationBars.js @@ -39,6 +39,10 @@ NavBarStageContainer.propTypes = { style: PropTypes.object, }; +NavBarStageContainer.defaultProps = { + style: {}, +}; + export class NavigationBars extends PureComponent { render() { const navBarDropDownOptions = [ diff --git a/examples/components/Stage.js b/examples/components/Stage.js index 3112df59..d8bb47eb 100644 --- a/examples/components/Stage.js +++ b/examples/components/Stage.js @@ -15,8 +15,13 @@ function Stage({ title, children }) { } Stage.propTypes = { - title: PropTypes.string, children: PropTypes.node, + title: PropTypes.string, +}; + +Stage.defaultProps = { + children: undefined, + title: undefined, }; const styles = { diff --git a/html/Html.js b/html/Html.js index a8917205..e0bf5063 100644 --- a/html/Html.js +++ b/html/Html.js @@ -19,12 +19,6 @@ const defaultElementSettings = { }; class Html extends PureComponent { - static propTypes = { - body: PropTypes.string.isRequired, - renderElement: PropTypes.func, - style: PropTypes.object, - }; - /** * Create Element class for given element tag and add it to the ElementClassMap. * Use the settings to additionally describe a Element class. @@ -151,6 +145,16 @@ class Html extends PureComponent { } } +Html.propTypes = { + body: PropTypes.string.isRequired, + style: PropTypes.object.isRequired, + renderElement: PropTypes.func, +}; + +Html.defaultProps = { + renderElement: undefined, +}; + export const ElementPropTypes = { childElements: PropTypes.array, renderElement: PropTypes.func, diff --git a/html/components/Gallery.js b/html/components/Gallery.js index 2ed42fc6..6eeb86b4 100644 --- a/html/components/Gallery.js +++ b/html/components/Gallery.js @@ -8,11 +8,6 @@ import { InlineGallery } from '../../components/InlineGallery'; * Style interface correspond to InlineGallery from @shoutem/ui. */ export default class Gallery extends PureComponent { - static propTypes = { - ...InlineGallery.propTypes, - handlePhotoPress: PropTypes.func, - }; - constructor(props) { super(props); @@ -53,3 +48,12 @@ export default class Gallery extends PureComponent { ); } } + +Gallery.propTypes = { + ...InlineGallery.propTypes, + handlePhotoPress: PropTypes.func, +}; + +Gallery.defaultProps = { + handlePhotoPress: undefined, +}; diff --git a/html/components/Image.js b/html/components/Image.js index 29567e3c..623ad90e 100644 --- a/html/components/Image.js +++ b/html/components/Image.js @@ -14,17 +14,6 @@ import { Lightbox } from '../../components/Lightbox'; * this component will determine the Image dimensions before rendering an image. */ export default class HtmlImage extends PureComponent { - static propTypes = { - ...RNImage.propTypes, - lightbox: PropTypes.bool, - allowUpscale: PropTypes.bool, - }; - - static defaultProps = { - lightbox: true, - allowUpscale: false, - }; - constructor(props) { super(props); @@ -108,3 +97,14 @@ export default class HtmlImage extends PureComponent { ); } } + +HtmlImage.propTypes = { + ...RNImage.propTypes, + allowUpscale: PropTypes.bool, + lightbox: PropTypes.bool, +}; + +HtmlImage.defaultProps = { + allowUpscale: false, + lightbox: true, +}; diff --git a/html/components/SimpleHtml.js b/html/components/SimpleHtml.js index 6ebb7fe4..6a8010a9 100644 --- a/html/components/SimpleHtml.js +++ b/html/components/SimpleHtml.js @@ -54,16 +54,6 @@ function resolveDimensions(objectToResize, style) { } class SimpleHtml extends PureComponent { - static propTypes = { - body: PropTypes.string, - attachments: PropTypes.array, - style: PropTypes.object, - customTagStyles: PropTypes.object, - customHandleLinkPress: PropTypes.func, - unsupportedVideoFormatMessage: PropTypes.string, - customAlterNode: PropTypes.func, - }; - constructor(props) { super(props); @@ -309,4 +299,23 @@ class SimpleHtml extends PureComponent { } } +SimpleHtml.propTypes = { + style: PropTypes.object.isRequired, + attachments: PropTypes.array, + body: PropTypes.string, + customAlterNode: PropTypes.func, + customHandleLinkPress: PropTypes.func, + customTagStyles: PropTypes.object, + unsupportedVideoFormatMessage: PropTypes.string, +}; + +SimpleHtml.defaultProps = { + attachments: undefined, + body: undefined, + customAlterNode: undefined, + customHandleLinkPress: undefined, + customTagStyles: undefined, + unsupportedVideoFormatMessage: undefined, +}; + export default connectStyle('shoutem.ui.SimpleHtml')(SimpleHtml); diff --git a/html/elements/A.js b/html/elements/A.js index e16e7e98..9f0147d2 100644 --- a/html/elements/A.js +++ b/html/elements/A.js @@ -9,12 +9,6 @@ import { isImg } from './Img'; import { Inline } from './Inline'; class A extends PureComponent { - static propTypes = { - ...ElementPropTypes, - handleLinkPress: PropTypes.func, - href: PropTypes.string, - }; - constructor(props, context) { super(props, context); @@ -63,6 +57,17 @@ class A extends PureComponent { } } +A.propTypes = { + ...ElementPropTypes, + handleLinkPress: PropTypes.func, + href: PropTypes.string, +}; + +A.defaultProps = { + handleLinkPress: undefined, + href: undefined, +}; + function openLinkPress(Component) { return function(props) { function handleLinkPress(href) { diff --git a/html/elements/Inline.js b/html/elements/Inline.js index f18ead44..3c4a9975 100644 --- a/html/elements/Inline.js +++ b/html/elements/Inline.js @@ -138,20 +138,6 @@ function renderGroupedChildren(groupedChildren, renderElement, style) { * @constructor */ export class Inline extends PureComponent { - static defaultProps = { - style: {}, - }; - - static propTypes = { - ...ElementPropTypes, - onPress: PropTypes.func, - onLineBreak: PropTypes.func, - }; - - static defaultProps = { - onLineBreak: handleLineBreak, - }; - render() { const { block, @@ -207,6 +193,19 @@ export class Inline extends PureComponent { } } +Inline.propTypes = { + ...ElementPropTypes, + style: PropTypes.object, + onLineBreak: PropTypes.func, + onPress: PropTypes.func, +}; + +Inline.defaultProps = { + style: {}, + onLineBreak: handleLineBreak, + onPress: undefined, +}; + export const InlineSettings = { display: blockDisplayIfAnyChildIsBlock }; export default combineMappers(mapElementProps)(Inline); diff --git a/html/elements/Text.js b/html/elements/Text.js index 07fd18f1..36ea4bbe 100644 --- a/html/elements/Text.js +++ b/html/elements/Text.js @@ -2,6 +2,7 @@ import React from 'react'; import { Text } from 'react-native'; import { AllHtmlEntities as Entities } from 'html-entities'; import _ from 'lodash'; +import PropTypes from 'prop-types'; import { combineMappers, ElementPropTypes, mapElementProps } from '../Html'; const html = new Entities(); @@ -57,6 +58,11 @@ export function TextElement(props) { TextElement.propTypes = { ...ElementPropTypes, + style: PropTypes.object, +}; + +TextElement.defaultProps = { + style: {}, }; export default combineMappers(mapElementProps)(TextElement); diff --git a/html/elements/Video.js b/html/elements/Video.js index ba9515fc..ab728a7a 100644 --- a/html/elements/Video.js +++ b/html/elements/Video.js @@ -22,11 +22,12 @@ function Video({ src, thumbnailUrl, style }) { Video.propTypes = { src: PropTypes.string, - thumbnailUrl: PropTypes.string, style: PropTypes.object, + thumbnailUrl: PropTypes.string, }; Video.defaultProps = { + src: undefined, style: { container: { alignSelf: 'stretch', @@ -34,6 +35,7 @@ Video.defaultProps = { alignItems: 'center', }, }, + thumbnailUrl: undefined, }; export default combineMappers(mapElementProps)(Video); diff --git a/html/elements/list/Li.js b/html/elements/list/Li.js index d0041e0b..62a0d8c4 100644 --- a/html/elements/list/Li.js +++ b/html/elements/list/Li.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { ElementPropTypes } from '../../Html'; import { Inline } from '../Inline'; @@ -30,7 +29,6 @@ function Li({ element, renderElement, style }) { Li.propTypes = { ...ElementPropTypes, - prefix: PropTypes.element, }; export default Li; diff --git a/html/elements/list/Ol.js b/html/elements/list/Ol.js index cc20f4b8..816d8224 100644 --- a/html/elements/list/Ol.js +++ b/html/elements/list/Ol.js @@ -28,4 +28,8 @@ Ol.propTypes = { style: PropTypes.object, }; +Ol.defaultProps = { + style: {}, +}; + export default combineMappers(mapElementProps)(Ol); diff --git a/html/elements/list/Ul.js b/html/elements/list/Ul.js index 1e80f3e8..45816f58 100644 --- a/html/elements/list/Ul.js +++ b/html/elements/list/Ul.js @@ -24,4 +24,8 @@ Ul.propTypes = { style: PropTypes.object, }; +Ul.defaultProps = { + style: {}, +}; + export default combineMappers(mapElementProps)(Ul); diff --git a/html/elements/list/prefix/Bullet.js b/html/elements/list/prefix/Bullet.js index 17564875..1db2b8aa 100644 --- a/html/elements/list/prefix/Bullet.js +++ b/html/elements/list/prefix/Bullet.js @@ -9,3 +9,7 @@ export default function BulletPrefix({ style }) { BulletPrefix.propTypes = { style: PropTypes.object, }; + +BulletPrefix.defaultProps = { + style: undefined, +}; diff --git a/html/elements/list/prefix/Number.js b/html/elements/list/prefix/Number.js index 05766b5a..066c484a 100644 --- a/html/elements/list/prefix/Number.js +++ b/html/elements/list/prefix/Number.js @@ -10,6 +10,11 @@ export default function NumberPrefix({ element, style }) { } NumberPrefix.propTypes = { - style: PropTypes.object, element: PropTypes.shape({ ...ElementPropTypes }), + style: PropTypes.object, +}; + +NumberPrefix.defaultProps = { + element: undefined, + style: undefined, }; From 3b8ed514f76d797952d77e361d2ffb498b69170e Mon Sep 17 00:00:00 2001 From: Definitely Not Vlad Date: Thu, 19 May 2022 12:01:59 +0200 Subject: [PATCH 3/6] Feature/apply prop and state destructuring (#710) * Adjust prop type and defaults declaration to match conventions * Re-add NumberInput style PropTypes.shape declaration * Add and correct prop/state destructuring * Fix ViewPropTypes usage, remove inappropriate defaultProps spread * Apply conventions to YearRangePicker (missed in initial sweep) * Replace usage of delete in Button * Address CRs by @sstimac & @tomislav-arambasic on #710 --- components/Button.js | 14 ++++----- components/DropDownMenu/DropDownModal.js | 8 +++-- components/EmptyStateView.js | 10 ++++--- components/FormGroup.js | 4 ++- components/HorizontalPager/HorizontalPager.js | 21 +++++++------ components/ImageGallery/ImageGalleryBase.js | 14 ++++++--- components/ImageGalleryOverlay.js | 2 +- components/ImagePreview.js | 11 +++---- .../InlineDropDownMenu/InlineDropDownMenu.js | 2 +- components/LinearGradient.js | 10 +++---- components/ScrollView/ScrollView.js | 14 ++++----- components/Touchable.js | 30 ++++++++----------- components/TouchableNativeFeedback.js | 20 +++++-------- components/TouchableOpacity.js | 18 ++++------- components/View.js | 14 ++++----- html/Html.js | 6 ++-- html/components/Image.js | 10 +++---- 17 files changed, 101 insertions(+), 107 deletions(-) diff --git a/components/Button.js b/components/Button.js index 662c4168..eabcc9e5 100644 --- a/components/Button.js +++ b/components/Button.js @@ -5,18 +5,14 @@ import { connectStyle } from '@shoutem/theme'; class Button extends PureComponent { render() { - // The underlayColor is not a valid RN style - // property, so we have to unset it here. - const style = { - ...this.props.style, - }; - delete style.underlayColor; + const { style, ...otherProps } = this.props; + const { underlayColor, ...otherStyle } = style; return ( ); } diff --git a/components/DropDownMenu/DropDownModal.js b/components/DropDownMenu/DropDownModal.js index 3b812108..2ac1ce14 100644 --- a/components/DropDownMenu/DropDownModal.js +++ b/components/DropDownMenu/DropDownModal.js @@ -60,14 +60,16 @@ class DropDownModal extends PureComponent { close() { const { onClose } = this.props; - if (onClose) { + if (_.isFunction(onClose)) { onClose(); } } emitOnOptionSelectedEvent(option) { - if (this.props.onOptionSelected) { - this.props.onOptionSelected(option); + const { onOptionSelected } = this.props; + + if (_.isFunction(onOptionSelected)) { + onOptionSelected(option); } } diff --git a/components/EmptyStateView.js b/components/EmptyStateView.js index c1193c61..cc4b7528 100644 --- a/components/EmptyStateView.js +++ b/components/EmptyStateView.js @@ -15,13 +15,15 @@ class EmptyStateView extends PureComponent { } onRetry() { - this.props.onRetry(); + const { onRetry } = this.props; + + onRetry(); } renderRetryButton() { const { retryButtonTitle } = this.props; - // Show retry button at the bottom only if there is an onRetry action passed. + // Show retry button at the bottom only if there is an onRetry action passed return (