facebook / react-native

A framework for building native applications using React

Home Page:https://reactnative.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Style] Defining a default style for components

yelled3 opened this issue · comments

consider the following use case;
my current project uses custom fonts, which means we want that all Text components have fontFamily: Fonts.Normal. (of course this can be any other style default)
my first intuition was to create a new component and use it all across the project, e.g

var Fonts = require('./../Fonts');

var DefaultText = React.createClass({
  propTypes: {
    style: Text.propTypes.style
  },
  render() {
    return (
      <Text style={[styles.text, this.props.style]}>{this.props.children}</Text>
    );
  }
});

var styles = StyleSheet.create({
  text: {
    fontFamily: Fonts.Normal
  }
});

IMO, this approach is very error prone, since it's very easy to forget about this and use the RN Text.
I'm interesting to know if currently there's an alternative to this approach?

I think that, just like a web app has a default.css, a RN app should provide a way to define defaults - some like:

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text
  } = React;

var defaultTextStyle = StyleSheet.create({
  text: {
    fontFamily: Fonts.Normal
  }
});

AppRegistry.registerComponentStyle(Text, defaultTextStyle)
// or maybe just
Text.defaultProps.style = defaultTextStyle

// before/after the app is registered?
AppRegistry.registerComponent('MyApp', () => MyApp);

Thoughts?

@ide @JohnyDays /cc

Setting a default font family seems like a reasonable use case. I don't know about setting other default styles though - those could easily interfere in unexpected ways with any external libraries that you include in your project that build on top of those and force you into a corner where you have to fork and modify those libraries. cc @vjeux

Any update here?
@brentvatne Didn't you code a "react-native-debug-stylesheet" once? Wouldnt it be possible to use the same method for a default fontFamily?

Being able to set defaults rather than using a custom text component everywhere is reasonable, and doing it at the Text component level, like Text.defaultProps.style = defaultTextStyle, seems like a good way to get it done, but I'm not sure it's really worth the added complexity since it's not that big a deal to use a custom text component. @vjeux, what do you think?

Text.defaultProps.style = defaultTextStyle is bad because it affects everything and can collide if you have two parts of the app using different defaults. One thing that would be better is to use context for the default font and size. This way you can scope it to a root.

Ah yes, context would be much better.

Still not sure it's worth supporting though, since it should be trivial to find-replace a custom text component.

On Jul 17, 2015, at 4:56 PM, Christopher Chedeau notifications@github.com wrote:

Text.defaultProps.style = defaultTextStyle is bad because it affects everything and can collide if you have two parts of the app using different defaults. One thing that would be better is to use context for the default font and size. This way you can scope it to a root.


Reply to this email directly or view it on GitHub.

Where context would be more powerful - for better or for worse - is when using 3rd party components that contain Text inside of them.

Someone who has thought a lot about accessibility, even from the web team, might have ideas about how text should be customized across an entire app.

One thing that would be better is to use context for the default font and size. This way you can scope it to a root.

@vjeux @sahrens could you please provide an example?

@yelled3 - here I'm using context to pass functions down to child components, you could do the same with styles: https://gist.github.com/brentvatne/db1cf9fa16f7fbc514cb

Here's a basic example with context:

class MyText extends React.Component {
  contextTypes: {
    textStyle: React.PropTypes.object,
  },
  render: function() {
    return (
      <Text style={[styles.defaultText, this.context.textStyle]}>{this.props.children}</Text>
    );
  },
}
class MyView extends React.Component {
  childContextTypes: {
    textStyle: React.PropTypes.object,
  },
  getChildContext: function() {
    return {textStyle: styles.overriddenTextStyle},
  },
  render: function() {
    return (
      <MyText>Foo</MyText>
    );
  },
}

Hi there! This issue is being closed because it has been inactive for a while.

But don't worry, it will live on with ProductPains! Check out it's new home: https://productpains.com/post/react-native/style-defining-a-default-style-for-components

so what is the best way to override the style some comment/global components like Text?

@rainchen create a component with your overriden styles, and then use that instead of text, and passthrough the rest of the props.

I want to advocate my library react-native-tachyons here, which gives you easy fontSize (and widths, heights etc.) relative to your root-fontsize. So you can change just one number and scale your entire app.

You can override the prototype as done in react-native-global-props package - https://github.com/Ajackster/react-native-global-props/blob/master/src/CustomFunctions/setCustomText.js#L8