Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix CalendarList rendering on react-native-web #1313

Closed
wants to merge 3 commits into from

Conversation

tedsta
Copy link

@tedsta tedsta commented Oct 24, 2020

This fixes CalendarList / Agenda rendering when running on web via Expo.

Thanks to @bkniffler with his fix for touch support on web here: https://github.com/bkniffler/react-native-calendars/commit/7a0f986bbef1f84b0fd6901af6974c8bcd7436c2

The main issue was that FlatList scrolling only works on web if the parent component has a flex style. Source: necolas/react-native-web#1436 (comment)

Also incorporated fixes for some PropTypes errors on web, thanks @nandorojo: #1033 (comment)

Fixes #924

@Inbal-Tish Inbal-Tish added the Web label Nov 26, 2020
@@ -35,7 +31,7 @@ export default class AgendaView extends Component {
/** Specify theme properties to override specific styles for calendar parts. Default = {} */
theme: PropTypes.object,
/** agenda container style */
style: viewPropTypes.style,
style: PropTypes.object,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'style' prop type should be PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]) as you can pass style inline as an object or array and you can pass it from a StyleSheet where it's just a number.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

typeof document !== 'undefined'
? PropTypes.shape({style: PropTypes.object})
: ViewPropTypes || View.propTypes;
const {Text, View, Dimensions, Animated, Platform} = ReactNative;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is 'import * as ReactNative from 'react-native';' still necessary? Can't we extract the components from 'react-native' without importing it all?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to be as non-invasive as possible - I'm new to JS / React. Would you like me to remove the 'import * as ReactNative' and fix anything that depends on it?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do want to remove the * import but I don't want to break anyone. Can you tell me how do you test this in web on old RN versions?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Err.. I haven't tested on older RN versions. Good idea. I'll make sure that works then post back here.

typeof document !== 'undefined'
? PropTypes.shape({style: PropTypes.object})
: ViewPropTypes || View.propTypes;
const {View} = ReactNative;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here. Why keep importing * from 'react-native'?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented above

@@ -119,6 +115,8 @@ export default class AgendaView extends Component {
};

this.currentMonth = this.state.selectedDay.clone();
this.onHover = this.onHover.bind(this);
Copy link
Collaborator

@Inbal-Tish Inbal-Tish Nov 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What these changes have to do with fixing the rendering? I think you're mixing two tasks here...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds mouse support so that the interactions can work on web. I stole this from here and credited the author in the main PR comment.

@@ -294,7 +291,7 @@ class CalendarList extends Component {

render() {
return (
<View>
<View style={{flex: 1}}>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what actually fixes the rendering - FlatList scrolling only works on web if the parent component has a flex style. Source: necolas/react-native-web#1436 (comment)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that's a style to fix a web rendering you should add it to a StyleSheet with Platform division. You can't change for all Platforms to fix one...

Copy link

@nandorojo nandorojo Dec 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tedsta Per @Inbal-Tish's comment, this line should look something like:

import { StyleSheet, Platform } from 'react-native'

...
render() {
  return <View style={Platform.select({ web: styles.webContainer, default: undefined })}>
}

const styles = StyleSheet.create({
  webContainer: {
    flex: 1
  }
})

Or, like this:

<View style={styles.container}>

const styles = StyleSheet.create({
  container: Platform.select({ web: { flex: 1 }, default: {} })
})

@@ -139,6 +146,16 @@ export default class AgendaView extends Component {
this.state.scrollY.removeAllListeners();
}

onHover() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are very specific implementations. If you're adding a feature, first, you should make a separate PR for that and not add it to another issue. Second, you should write an API that lets the user adjust these implementations if required.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure I'll split the mouse interactions into a second PR. Unless @bkniffler wants it since it is their code :) LMK

For API/adjustable-ness - none of the other interactions have this AFAICT? Am I missing something?

Copy link

@nandorojo nandorojo Dec 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these hover interactions are crucial for web support. In my opinion, they should be moved to a separate PR to help get this one merged sooner.

The right way to do this would probably be to transfer over to React Native's new Pressable (available in 0.63), and style it like so:

<Pressable
  // react-native-web 0.14 added support for hovered here 🔥
  style={({ hovered, pressed }) => {
    opacity: pressed || hovered ? 0.7 : 1
  }}
/>

I'm not sure how focused on backwards-compatibility this library is, though. So this might be a later priority.

Comment on lines +317 to +318
//initialScrollIndex={1}
onScrollToIndexFailed={() => {}}
Copy link
Member

@emilisb emilisb Dec 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the comment.
Is onScrollToIndexFailed={() => {}} necessary? It does nothing.

@francisleigh
Copy link

Keen to install this after PR is merged :-)

@nandorojo
Copy link

Thank you guys for your hard work on this, looking forward to installing it when it's merged!

@yoangau
Copy link
Contributor

yoangau commented Feb 2, 2021

Hi guys, I was wondering if there was some way to patch this from our side while this issue is being resolved? Is there a way to access the necessary view to add flex: 1 using the theme of CalendarList?

@tedsta
Copy link
Author

tedsta commented Feb 8, 2021

Sorry guys, I'm in a new job now and don't work with React anymore 😧 Hopefully one of you guys can fork this and push it over the finish line. I'll leave this open but feel free to close.

@yoangau
Copy link
Contributor

yoangau commented Feb 8, 2021

Following the last comment I opened this PR: #1405

@Inbal-Tish
Copy link
Collaborator

@tedsta Please see merged PRs #1424 and #1405 if that solves your issue.

@Inbal-Tish Inbal-Tish closed this Apr 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

calendar not rendering properly with expo web
6 participants