I have a file that I am using to define global styles. I would like to define a const within the file to use for the underlineColorAndroid prop.
My global stylesheet looks like this:
const React = require('react-native')
const { StyleSheet } = React
const underlineColorAndroid = '#F86C51'
module.exports = StyleSheet.create({
background: {
backgroundColor: '#F5FCFF',
},
})
I import the file like this:
import globalStyles from '../styles/global'
And I use the style within the prop like this:
underlineColorAndroid={globalStyles.underlineColorAndroid}
This doesn't work, any ideas how I can do this?
Instead of using the module.exports syntax, you can use the ES6 export statements to define both default and named exports:
export const underlineColorAndroid = '#F86C51'
export default StyleSheet.create({
background: {
backgroundColor: '#F5FCFF',
},
})
The default export can be imported as before:
import globalStyles from '../styles/global';
The named exports can be imported using curly braces to denote destructuring:
import { underlineColorAndroid } from '../styles/global';
Or both at the same time:
import globalStyles, { underlineColorAndroid } from '../styles/global';
However, it might be better to split the style sheet and the named variables into different files for clarity.
Related
I'm trying to pass my theme object to styled-components on my Next.js project, but it keep's failing to receive it as a props.
That's my _document.tsx
import { getInitialProps } from "#expo/next-adapter/document";
import Document, { DocumentContext, DocumentInitialProps } from "next/document";
import { ServerStyleSheet } from "styled-components";
export default class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps> {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
});
const initialProps = await getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} finally {
sheet.seal();
}
}
}
After that I wrapped my _app.tsx with the ThemeProvider
import Layout from '../components/Layout'
import 'setimmediate';
import { ThemeProvider } from 'styled-components';
import { wrapperStore } from "../store";
import { ApolloProvider } from "#apollo/client";
import client from './api/apollo-client';
import React from 'react';
import lightTheme from '../helpers/light-mode';
import { AppProps } from 'next/app';
function MyApp({ Component, pageProps }: AppProps) {
return (
<React.Fragment>
<ApolloProvider client={client}>
<ThemeProvider theme={lightTheme}>
<Layout>
<Component {...pageProps} />
</Layout>
</ThemeProvider>
</ApolloProvider>
</React.Fragment>
)
}
export default wrapperStore.withRedux(MyApp);
From here I receive a warning when I try to wrap my component, exporting it withTheme
[withTheme] You are not using a ThemeProvider nor passing a theme prop or a theme in defaultProps in component class "Connect(Front)"
when I try to console log theme from my props, it returns undefined, and when I create a styled component, trying to use theme as props it causes an error
export const RecruitmentTextLocation = styled.Text`
fontSize: ${scaleFont(15)};
textAlign: left;
marginTop: ${scale(5)}px;
marginBottom: ${scale(1)}px;
fontFamily: roboto;
fontWeight: 500;
color: ${({theme}) => theme.colors.cardTitleColor};
`;
TypeError: Cannot read property 'colors' of undefined
I'm really stuck on how I can use theming with styled-components on Nextjs.
I suppose you problem is in light-mode.tsx. How can i see you use typescript in that case need create a declarations file and DefaultTheme interface. example
Create a declarations file
TypeScript definitions for styled-components can be extended by using declaration merging since version v4.1.4 of the definitions. documentation
light-mode.tsx
import { DefaultTheme } from 'styled-components';
export const lightTheme: DefaultTheme = {
colors: {
cardTitleColor: red;
}
};
I was looking for the same and found a solution for typing the theme object you receive as prop on your styled components.
First, export the types of your themes, e.g.:
export type LightTheme = typeof lightTheme;
Then add a src/declaration.d.ts file with the below, so to enhance the DefaultTheme exported by styled-components to be typed with your custom theme object:
import { Theme } from "globalStyles";
declare module "styled-components" {
export interface DefaultTheme extends Theme {}
}
From there you won't need any withTheme to use your theme object, as you will simply be able to access it through:
color: ${({theme}) => theme.colors.cardTitleColor};
I couldn't find the current method for achieving this. It used to be:
'use strict';
var React = require('react-native');
var { StyleSheet } = React;
module.exports = StyleSheet.create({
});
In a separate file and then you would require it as follows:
var styles = require('./styles');
But that no longer seems to work?
in styles.js file, you can do
import { StyleSheet } from 'react-native';
const styles = StyleSheet.create({
});
export default styles;
and in other files
import styles from './styles';
You can just do the following:
Style.js
import { StyleSheet } from 'react-native';
export default Style = StyleSheet.create({
// your styles here
container: {
flex: 1
}
});
And then you import your StyleSheet with:
import Style from 'PATH_TO_STYLE.js';
and then you can use it with:
<View style={Style.container} />
I need to create a custom font that applies to every Text component in the whole application.
Is there is a way to set a font globally in React Native?
One way is to create a wrapper for RN Text say MyTextCustomFont:
const MyTextCustomFont = (props) => {
return (
<Text style={{fontFamily:'myFont'}} {...props} >{props.children}</Text>
)
}
import this MyTextCustomFont and use anywhere.
Another way is to define a style object and use it wherever you want.
To do this we have to implement a method in which we will override Text component creation in React Native. In this we will set default font family or size or any attribute we want to set by default.
// typography.js
import React from 'react'
import { Text, Platform, StyleSheet } from 'react-native'
export const typography = () => {
const oldTextRender = Text.render
Text.render = function(...args) {
const origin = oldTextRender.call(this, ...args)
return React.cloneElement(origin, {
style: [styles.defaultText, origin.props.style],
})
}
}
const styles = StyleSheet.create({
defaultText: {
fontFamily: 'NunitoSans-Regular',//Default font family
}
});
Then in index.js you have to do this:
import { typography } from './src/utils/typography'
typography()
Detailed answer here:
https://ospfolio.com/two-way-to-change-default-font-family-in-react-native/
I think your problem is add Custom Fonts in react native.
1. Add Your Custom Fonts to Assets
Add all the font files you want to an “assets/fonts” folder in the root of your react native project:
2. Edit Package.json
Adding rnpm to package.json providing the path to the font files:
"rnpm": {
"assets": [
"./assets/fonts/"
]
},
3. Link assest files
run this command in your react native project root folder
react-native link
This should add the font references in your Info.plist file for iOS and on Android copy the font files to android/app/src/main/assets/fonts.
4. Add in stylesheet
Add a fontFamily property with your font name:
const styles = StyleSheet.create({
title: {
fontSize: 16,
fontFamily: 'PlayfairDisplay-Bold',
color: '#fff',
paddingRight: 20,
},
});
So, I've made a component doing this quite easely some times ago. This is working with Expo, I don't know for vanilla react-native.
at the start of your app:
import { Font, Asset } from 'expo'
async initFont() {
try {
await Font.loadAsync({
'Bariol': require('src/assets/font/Bariol_Regular.otf'),
'Bariol Bold': require('src/assets/font/Bariol_Bold.otf'),
})
this.setState({ fontReady: true })
} catch (e) {
console.log(e)
}
}
Then, you have to create a component file like text.js containing this code:
export default function (props) {
let font = { fontFamily: 'Bariol' }
if (props.bold) {
font = { fontFamily: 'Bariol Bold' }
}
const { bold, style, children, ...newProps } = props
return (
<Text {...newProps} style={[Style.text, props.style, font]}>
{props.children}
</Text>
)
}
Finally, in any of you other component / page just import MyText:
import Text from 'path/to/text.js'
use it like a normal Text component:
<Text bold>Hello World!</Text>
Even if this solution looks a bit more complicated than the others, it is easier to use once the setup is ok, since you just have to import Text.
You can override Text behaviour by adding this in any of your component using Text:
Edit: Add this code in your App.js or main file
let oldRender = Text.render;
Text.render = function (...args) {
let origin = oldRender.call(this, ...args);
return React.cloneElement(origin, {
style: [{color: 'red', fontFamily: 'Arial'}, origin.props.style]
});
}
For react Native Version 0.56 or below, Add this code in your App.js or main file
let oldRender = Text.prototype.render;
Text.prototype.render = function (...args) {
let origin = oldRender.call(this, ...args);
return React.cloneElement(origin, {
style: [{color: 'red', fontFamily: 'Arial'}, origin.props.style]
});
};
Reference
Or create your own component, such as MyAppText.
MyAppText would be a simple component that renders a Text component using your universal style and can pass through other props, etc.
I use a wrapper with default props like this :
const CustomText = ({ fontFam = "regular", ...props }) => {
const typo = {
light: "Montserrat_300Light",
regular: "Montserrat_400Regular",
bold: "Montserrat_600SemiBold",
};
return (
<Text {...props} style={[{ fontFamily: typo[fontFam], ...props.style }]}>
{props.children}
</Text>
);
};
export default CustomText;
By default, if "fontFam" is not indicated it will be regular font.
An example with bold typo :
<CustomText fontFam="bold" style={{ marginTop: 30, color: "grey" }}>
Some Text
</CustomText>
You can replace all your <Text/> by <CustomText />.
If you don't have to create custom component, you could try react-native-global-font. It will be apply for your all Text and TextInput
yes
app.js
import styles from './styles';
{...}
<Text style={styles.text}>hello World </Text>
{...}
styles.js
import {StyleSheet} from 'react-native';
const styles = StyleSheet.create({
text: {
// define your font or size or whatever you want to style here
},
use style on every text and all changes will affect all text components
I am trying to setup global styles in react-native.
I have imported
import {injectGlobal} from 'styled-components';
and have
class XoxoContainer extends Component {
render() {
return <Xoxo {...this.props} />
}
}
injectGlobal`
font-family: '20'
`;
But I keep getting styledComponents.injectGlobals is not a function. in the console.
That function is not part of the library on react-native according to this Github issue. That's why it keeps saying that it's not a function, because it can't find it.
create a styles.js file like this:
import React, {Component} from 'react';
import {
Platform,
StyleSheet
} from 'react-native';
export const styles = StyleSheet.create({
view_flex_one_white: {
flex: 1,
backgroundColor: white
}});
and use this anywhere in your app with import
import {styles} from "...link to file/styles";
render(){
return(
<View style={styles.view_flex_one_white}>
</View>
)
}
Create a js file with this pattern:
'use strict';
var React = require('react-native');
var myStyle = React.StyleSheet.create({
style1: { },
style2: { }
)}
module.exports = myStyle;
your component js use require to use that style sheet
var customStyle = require('../the/path/to/commonStyleSheet');
Use now like this:
<View style = {customStyle .style1} />
I want to make 2 variables for the main colors which can be used on the whole app. Here is the code:
import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
const primary = '#27bcb5';
const secondary = '#ffffff;
How can I export these 2 variables together for using on the app components?
Issue with the solution is :
import {DefaultStyle} from './variables';
const screenHeight = Dimensions.get("window").height;
const styles = {
wrapper: {},
slide1: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: primary,
it says can't find variable primary
You can export them with:
import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
const primary = '#27bcb5';
const secondary = '#ffffff';
export const DefaultStyle = {
primary,
secondary,
}
So you can use them as:
import { DefaultStyle } from './default-variables';
console.log(DefaultStyle.primary);
console.log(DefaultStyle.secondary);
You could do a named export. E.g. :
import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
const primary = '#27bcb5';
const secondary = '#ffffff';
export { primary, secondary };
After that, you can import your styles via:
import { primary, secondary } from 'YOUR_FILE_PATH'
// Declarations of colors variables
const Maincolor ="#333640"
const Backgroundcolor = "#FFFFFF"
const Gridcolor = "#A7A9AB"
const colors = // Made to be bind in one because only one export is possiable
{
Maincolor,
Backgroundcolor,
Gridcolor,
}
export default colors; // exporting as default
// And in your main code where you have to include
import colors from 'path_of_the_file'
// then in styles use
style ={{backgroundColor:color.Maincolor}} // example how to use
I like to do something better, define a global file where you can save like Moment() time, Device Measures, etc.
global.js
const global = {
PRIMARY: '#27bcb5',
SECONDARY: '#ffffff,
DEVICE_MEASURES:{
WIDTH: Dimensions.get("window").width,
HEIGHT: Dimensions.get("window").height;
},
...
}
export default global
And then in your code:
import GLOBAL from '(directory)/global'
<View style={{ width: GLOBAL.DEVICE_MEASURES.WIDTH }}>
<Text style={{ color: GLOBAL.PRIMARY }}>
sup
</Text>
</View>
It's just better to have a global file where you can store all your app's configurations.