How to define multiple constants in config.js - javascript

I am trying to save some PIXIJS styles in a config.js file, so that I could reuse these style contants in other JavaScript files.
Is it possible to define these multiple constants (fontFamily, fontSize, and fill) together in the config-file?
const styleText = new PIXI.TextStyle({
fontFamily: "Arial",
fontSize: "20",
fill: "0xf0000f",
});

Create js file
export default class{
fontFamily: "Arial",
fontSize: "20",
fill: "0xf0000f",
}
and in your file use
import TextStyle from './path/to/config.js';
const styleText = new PIXI.TextStyle(TextStyle);
If you need to have separate values alongside TextStyles object add these lines to config.js
export const lbl1 = 'lbl1';
export const lbl2 = 'lbl2';
and change import statement to:
import TextStylel, {bl1, lbl2} from './path/to/config.js';

Related

Fontawesome icons not accepting color props through react functional components via tailwindcss

My Problem
I have a project which requires icons everywhere. Instead of rendering a Fontawesome Icon in every script, I have a functional component which renders an icon when given props.
When calling the function, sometimes it doesn't accept the color prop. Only certain colors seem to be working, such as darkBlue, lightBlue, and green. Colors which haven't accepted the prop are defaulting to white.
I'm using Tailwindcss to inject classes into the components.
Tailwind Config
module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
theme: {
colors: {
dark: "#121212",
white: "#fff",
secondary: "#F0A500",
lightBlue: "#0EA5E9",
darkBlue: "#2563EB",
beige: "#FDBA74",
silver: "#9CA3AF",
red: "#DC2626",
green: "#10B981",
orange: "#F97316",
hotPink: "#EC4899",
purple: "#6D28D9",
yellow: "#FDE047",
},
extend: {
},
},
plugins: [],
};
FC: Icon Render
import React from "react";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
// color props must be passed as a string
function Icon({ name, color, scale }) {
return (
<FontAwesomeIcon
icon={name}
className={`text-${color}`}
size={scale}
/>
);
}
export default Icon;
Calling Icon Render
import React from "react";
import Button from "../../shared/components/Button";
import Typography from "../../shared/utilities/Typography";
import Mugshot from "../../shared/assets/mugshot.jpg";
import Icon from "../../shared/components/Icon";
import {
faGlobe,
faHandSpock,
faComment,
} from "#fortawesome/free-solid-svg-icons";
import Avatar from "../../shared/components/Avatar";
function example() {
return (
<section className="section" id="home-hero">
<Typography variant="label">Some text</Typography>
<Typography variant="h2">
Some text <Icon name={faHandSpock} color="beige" />
</Typography>
</section>
);
}
export default example;
What I've Tried / Fun Facts
No errors in the console.
Some colors may be preserved tailwind color names?
Tried changing color names in tailwind config
Tried changing hex values in tailwind config
Conclusion
Edit: Discovered an easier way:
<Icon name={faHandSpock} color="text-beige" /> // full classname
// remove partial className, pass in object
function Icon({ name, color, scale }) {
return (
<FontAwesomeIcon
icon={name}
className={color}
size={scale}
/>
);
}
export default Icon;
TailwindCSS doesn't allow you to generate classes dynamically. So when you use the following to generate the class…
className={`text-${color}`}
…TailwindCSS will not pick that up as a valid TailwindCSS class and therefore will not produce the necessary CSS.
Instead, you must include the full name of the class in your source code.
For this you can create any function which returns the required string like this:
function changeFAColor (color) {
if(color === dark) return "text-dark"
(color === white) return "text-white"
(color === secondary) return "text-secondary")
.
.
.
(color === purple) return "text-purple")
(color === yellow) return "text-yellow")
}
And use it in the component
<FontAwesomeIcon
icon={name}
className={`${changeFAcolor(color)}`}
size={scale}
/>
Tailwind generates a CSS file which contains only the classes that you've used in the project.
The problem you're experiencing is because Tailwind doesn't recognise the generated class you're applying in "FC: Icon Render". In particular, this line:
className={`text-${color}`}
To quote the documentation:
The most important implication of how Tailwind extracts class names is
that it will only find classes that exist as complete unbroken strings
in your source files.
If you use string interpolation or concatenate partial class names
together, Tailwind will not find them and therefore will not generate
the corresponding CSS:
https://tailwindcss.com/docs/content-configuration#class-detection-in-depth
To resolve your problem, either pass in the full class name instead of generating it or safelist all of your text-{color} classes in your config file.
Assign your colors to a variable:
const colors = {
dark: "#121212",
white: "#fff",
...
Pass them into your config for theme:
theme: {
colors,
. . .
Safelist your colors:
safelist: Object.keys(colors).map(color => `text-${color}`),

declaration merging for react-native-elements theme

I am using react-native-elements in my react-native application.
My app is wrapped with the ThemeProvider to pass the theme down to all components.
<SafeAreaProvider>
<ThemeProvider theme={Theme}>
<Loader visible={loader.loading} text={loader.message} absolute={true} />
<RootNavigation />
</ThemeProvider>
</SafeAreaProvider>
In the theme file i define the values i want to use across the app.
const theme = {
colors: {
primary: '#6A69E2',
primaryDark: '#4747c2',
primaryLight: 'rgba(106, 105, 226, 0.35)',
gray: {
dark: '#242424',
default: '#666',
medium: '#999',
light: '#ccc',
lightest: '#e7e7e7',
},
},
text: {
size: {
small: 12,
default: 16,
large: 18,
h1: 26,
h2: 22,
h3: 20,
},
},
Text: {
style: {
fontSize: 16,
color: '#242424',
fontFamily: 'Roboto',
},
},
Button: {
style: {
borderRadius: 50,
},
disabledStyle: {
backgroundColor: 'rgba(106, 105, 226, 0.35)',
},
},
};
export default theme;
For the values the original theme of react-native-elements providing this is working. For example i can access the colors by using
const theme = useTheme()
theme.colors.primary
But when i want to add some new properties like primaryDark i'll get an linter error.
Object literal may only specify known properties, and 'primaryDark' does not exist in type 'RecursivePartial<Colors>'.ts(2322)
In the doc of react-native-elements is a part about declaration merging, but i don't understand how i can archive this
https://reactnativeelements.com/docs/customization/#typescript-definitions-extending-the-default-theme.
Somebody could help me with this?
Well, declaration merging still works. This seems like a bug on the lib's part.
Their doc says you can augment the Color interface in module 'react-native-elements'. But currently (as of 2021-04-18, with v3.3.2) that interface is actually hidden inside module 'react-native-elements/dist/config/colors', not directly exposed at the top level, weird.
I suggest you file an issue to their repo. Never mind, someone already filed the issue.
Tested on my machine, following solution works.
import React from 'react'
import { useTheme, ThemeProvider } from 'react-native-elements'
declare module 'react-native-elements/dist/config/colors' {
export interface Colors {
primaryDark: string
primaryLight: string
}
}
const ChildComp = () => {
const theme = useTheme()
theme.theme.colors.primaryDark // <-- No more error 🎉
return <div>foobar</div>
}
Reply to OP's comment. You can augment interface however you like, as long as the augmented key doesn't exist before. For example add foobar key to FullTheme.
declare module 'react-native-elements' {
export interface FullTheme {
foobar: string
}
}

Tree shaking not working for node package

I have a node module that is generally shaped like this (simplifying for example's sake):
# color.js
export var red = '#f00';
export var yellow = '#ff0';
export var blue = '#00f';
# images.js
export var image1 = '<base64 string approximately ~ 500kb>';
export var image2 = '<base64 string approximately ~ 500kb>';
# index.js
// JavaScript tokens
import * as colorExport from './color';
import * as imagesExport from './images';
export var color = colorExport;
export var images = imagesExport;
And then in my Next.js app (also tested in Create React App) I import the value like this:
# Home
import { color } from 'my-module'
const Home = () => (
<h1 style={{ color: color.red }}>Hello!</h1>
)
export default Home
This works fine. However, in both Next.js and Create React App, when I go to build the production-ready site EVERYTHING from my-module (color and images) is included and the final bundle size is a little greater than 1MB.
Now, if I change the import statement in Home to this:
import * as color from 'my-module/color'
Then the final bundle only includes the color values as I would expect. But I would like to not have to import so specifically. Is there something obvious I'm doing wrong here?
Refactoring color and images to have a default export rather than named exports and then also rewriting the way index import and exports fixed the problem.
E.g.
# color.js
export default {
red: '#f00',
yellow: '#ff0',
blue: '#00f'
}
# index.js
export { default as color } from './color';
export { default as images } from './images';

Best approach for managing strings in react native

I am new in react native. I've been dealing with this big project, that contains too many strings that can be reused many places in the project. So I created a strings.js file , as in android's strings.xml, to store all reusable strings in one file like this,
export const SOME_STRING = 'Some value';
export const ANOTHER_STRING = 'Another value';
...
and imports whenever i needed.
So these are my questions...
1) Is this a good approach ?
2) Is there any alternative to this ?
You don't need to export each value. One better way I know is to export
const SOME_STRING = 'Some value';
const ANOTHER_STRING = 'Another value';
module.exports = {
SOME_STRING:SOME_STRING,
ANOTHER_STRING:ANOTHER_STRING
}
Or you may like to wrap all of this in 1 constant object
const APPLICATION_CONSTANTS = {
SOME_STRING : 'Some string',
ANOTHER_STRING : 'Another string'
}
export default APPLICATION_CONSTANTS;
Usage
import APPLICATION_CONSTANTS from './strings';
APPLICATION_CONSTANTS.SOME_STRING
I am assuming you are using a lot of string because of styling. I do the same thing where I try to extract the maximum amount of styling information to a separate folder with different styling files. Not only variables, but commonly grouped styles as well.
For example:
const styleVariables = {
// Fonts
baseFontSize: 16,
largeFontSize: 24,
// Icons
smallIconSize: 24,
mediumIconSize: 36,
// Colors
mainColor: '#e85e45',
secondaryColor: '#a0c5d8',
offWhite: '#f4f4f4',
darkColor: '#404040',
// Dimensions
headerHeight: 70,
shadowSize: 6
};
export default styleVariables;
And I reference my variables in other styling files where related information is grouped:
/* presentation.js */
import variables from './variables';
export const shadow = {
shadowColor: variables.darkColor,
shadowRadius: variables.shadowSize,
shadowOpacity: 0.35,
shadowOffset: {width: 0, height: 0}
};
export const centered = {
alignItems: 'center'
justifyContent: 'center'
}
And in then in my components I just reference my styles:
import variables from './../styles/variables';
import {centered, shadow} from './../styles/presentation';
class RoundButton extends React.PureComponent {
render() {
return (
<View style={styles.button}>
{this.props.children}
</View>
);
}
}
const styles = StyleSheet.create({
button: {
width: variables.buttonSize,
height: variables.buttonSize,
borderRadius: variables.buttonSize / 2,
...centered
...shadow
}
For text styles and common presentations this really reduces code, and allows for easy modification in just one place.
Simple just you need to create one constantString.js file, and whenever you want to use string from the constantString.js file just import in particular file.
constantString.js
module.exports = {
SOME_STRING : 'Some string',
ANOTHER_STRING : 'Another string'
}
Use string from constantString.js something like,
import constStr from './constantString';
console.log(constStr.SOME_STRING); // Some string
console.log(constStr.ANOTHER_STRING); // Another string
You can use react-intl to play with strings, dates and numbers.
which will provide default functions to handle your data.
import { defineMessages } from 'react-intl';
const messages = defineMessages({
SOME_STRING : 'Some value',
ANOTHER_STRING : 'Another value',
});
export default messages;
learn more about react-intl library

is it possible to separate var styles = StyleSheet.create from React.component into different script in react native?

is it possible to separate var styles = StyleSheet.create from React.component into different script in react native?
that's possible. just create a js file with this pattern:
'use strict';
var React = require('react-native');
var myStyles = React.StyleSheet.create({
style1: { },
style2: { }
)}
module.exports = myStyles;
then in your component js use require to use that style sheet e.g. assuming your style js file is named phongyewtong.js
var s = require('../the/path/to/phongyewtong');
usage:
<View style = {s.style1} />
Both of the below links explain very well how to move styles out of your 'structural' code :
https://hackernoon.com/manage-react-native-project-folder-structure-and-simplify-the-code-c98da77ef792
https://medium.com/the-react-native-log/tips-for-styling-your-react-native-apps-3f61608655eb
Basically (copying code snippet from above link #2) have your styles in separate JS, say text.js file :
const text = StyleSheet.create({
p: {
color: 'black',
fontFamily: 'Open Sans',
fontSize: 14,
},
title: {
fontWeight: 'bold',
color: 'black',
fontFamily: 'Open Sans',
fontSize: 20,
}
});
export default text;
In React component, you can simply import this text style, and use it directly
<Text style={text.p}>settings</Text>
Hope this helps.
In a more recent React Version (0.31) I used this code:
import React, { Component, PropTypes } from 'react';
import { StyleSheet } from 'react-native';
var styles = StyleSheet.create({
...
});
module.exports = styles;

Categories