how to load scss module as object? - reactjs

According to Using SASS#3
By default, Laravel Mix will handle any import for SASS files. This means that anytime you do a import styles from 'blabla.scss', Mix will fetch that object and parse its CSS.
in my case CSS Modules can not operate properly with Laravel Mix (4.1.4)/ React 16.2.0
// webpack.mix.js
const mix = require('laravel-mix');
let rules = [
{
test: /\.ico$/,
loaders: ['file-loader']
}
];
mix.react('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.webpackConfig(
{
module: {
rules: rules
}
}
);
mix.browserSync('localhost:8000');
I'm trying to import a SCSS module like this:
my React component Progress.js
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import {
Progress as BsProgress
} from 'reactstrap';
import classes from './../../../sass/Progress.scss';
const Progress = (props) => {
const { children, slim, className, ...otherProps } = props;
const progressClass = classNames(className, {
[classes['slim']]: slim
});
return (
<BsProgress className={ progressClass } { ...otherProps }>
{ !slim && children }
</BsProgress>
);
};
Progress.propTypes = {
slim: PropTypes.bool,
className: PropTypes.string,
children: PropTypes.node
};
export { Progress };

Just try importing a .module.scss
import classes from './../../../sass/Progress.module.scss'

Related

Redux state change not reflected when connecting multiple React modules to same store

I am working on a React application (not CRA template) which consists multiple modules and I am trying to connect some of the modules to same Redux store so that they can share the same state and actions, e.g. Module A and B are connecting to same store, and whenever Module A dispatch state change, Module B should react to it.
However I notice Module B seems not to be receiving the state change triggered by Module A even though Redux Devtools did show a state changed from Module A. Below is my code and screenshot of Redux and React Devtools.
Module A
import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";
import { useDispatch } from "react-redux";
import { setVisibility } from "../../commonComponents/PageLoadingAnimation/reduxSlice";
// import { setActionsDialog } from "../../commonComponents/ActionsDialog/reduxSlice";
import { iso31661 } from "iso-3166";
import { allCountries } from "country-telephone-data";
import _ from "lodash";
import { Provider } from "react-redux";
import store from "../../store";
// Sort iso-3166 country list alphabetically based on its names
const sortedCountryList = iso31661?.sort((a, b) => a.name.localeCompare(b.name));
const BuyerRegister = () => {
/*** 1 ***/ const [birthDate, setBirthDate] = useState();
/*** 2 ***/ const [countrySelection, setCountrySelection] = useState(sortedCountryList[0]?.alpha2); // Set first country as default value
/*** 3 ***/ const [codeSelection, setCodeSelection] = useState(`${allCountries?.[0]?.iso2?.toUpperCase()}(${allCountries?.[0]?.dialCode})`);
/*** 4 ***/ const [phoneNumber, setPhoneNumber] = useState("");
/*** 5 ***/ const [formErrors, setFormErrors] = useState({});
const dispatch = useDispatch();
useEffect(() => {
dispatch(setVisibility(true));
}, []);
return (
<>
Buyer Register page
</>
)
}
ReactDOM.render(
(
<React.StrictMode>
<Provider store={store}>
<BuyerRegister />
</Provider>
</React.StrictMode>
),
document.getElementById("root")
);
Module B
import React, { useEffect } from "react"
import ReactDOM from "react-dom";
import { Provider, useSelector } from "react-redux";
import store from "../../store";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faSpinner } from "#fortawesome/free-solid-svg-icons";
import { Box } from "#mui/material";
import classes from "./styles.scss";
import styles from "./styles";
const PageLoadingAnimation = () => {
const { isVisible } = useSelector(state => state.pageLoadingAnimation);
useEffect(() => {
console.log("is visible udpated: ", isVisible);
}, [isVisible]);
return (
<>
{
isVisible ? (
<Box component="div" sx={styles.animationWrapper}>
<Box component="div" sx={styles.iconWrapper}>
<FontAwesomeIcon icon={faSpinner} className={classes["spinner-icon"]} size="3x" />
</Box>
<Box component="div">
Loading
<Box component="span" className={classes["first-dot"]}>.</Box>
<Box component="span" className={classes["second-dot"]}>.</Box>
<Box component="span" className={classes["third-dot"]}>.</Box>
</Box>
</Box>
) : null
}
</>
);
}
ReactDOM.render(
(
<React.StrictMode>
<Provider store={store}>
<PageLoadingAnimation />
</Provider>
</React.StrictMode>
),
document.getElementById("page-loading-animation")
);
Redux store
import { configureStore } from "#reduxjs/toolkit";
import pageLoadingAnimationReducer from "../commonComponents/PageLoadingAnimation/reduxSlice";
// import actionsDialogReducer from "../commonComponents/ActionsDialog/reduxSlice";
export default configureStore({
reducer: {
pageLoadingAnimation: pageLoadingAnimationReducer,
// actionsDialog: actionsDialogReducer
}
});
Webpack configuration
const path = require("path");
const webpack = require("webpack");
const dotenv = require("dotenv");
var config = {
cache: false,
entry: {
bodyHeader: ["babel-polyfill", path.resolve("./src/commonComponents/BodyHeader/index")],
bodyFooter: [path.resolve("./src/commonComponents/BodyFooter/index")],
pageLoadingAnimation: [path.resolve("./src/commonComponents/PageLoadingAnimation/index")],
// actionsDialog: [path.resolve("./src/commonComponents/ActionsDialog/index")],
buyerLogin: [path.resolve("./src/pages/BuyerLogin/index")],
buyerRegister: [path.resolve("./src/pages/BuyerRegister/index")]
},
output: {
filename: "[name].bundled.js",
path: path.join(__dirname, "/build")
},
module: {
rules: [
{
loader: "babel-loader",
test: /\.js$/,
exclude: /node_modules/
},
{
test: /\.s[ac]ss$/i,
use: [
"style-loader", // Inject CSS into DOM
{
// Resolve syntax "#import" and "url()" into JS readable "import / require()"
loader: "css-loader",
options: {
modules: {
localIdentName: "[local]--[hash:base64:7]"
}
}
},
"sass-loader", // Loads SASS / SCSS file and compile it to CSS
]
},
{
test: /\.css$/i,
use: [
"style-loader",
"css-loader"
]
}
]
},
plugins: [
new webpack.DefinePlugin({
"process.env": JSON.stringify(dotenv.config().parsed)
})
]
}
module.exports = (env, arg) => {
if(arg.mode === "development"){
config.devtool = "source-map";
config.watch = true; // To enable hot reload whenever file changes
config.watchOptions = {
aggregateTimeout: 300 // To add delay before rebuilding once first file changed, to
// aggregate any other changes made during this time period into
// one rebuild
}
}
config.mode = arg.mode || "development";
return config;
}
ExpressJS view template
doctype html
html
head
title Genuine Ecomm
style.
body {
margin: 0px;
}
body
//------------ Module B ------------//
include pageLoadingAnimation.pug
include bodyHeader.pug
//------------ Module A and its bundled JS is inside this block ------------//
block content
include bodyFooter.pug
block scripts
//------------ Module B's bundled JS file ------------//
script(src="/pageLoadingAnimation.bundled.js")
script(src="/bodyHeader.bundled.js")
script(src="/bodyFooter.bundled.js")
Redux Devtools when Module A dispatch state change
Module B useSelector state status
My objective is to make Module B (this is a loading animation) as a common component which can be used by different modules (like Module A) and to have a consistence and easy way to update Module B's state when necessary. Also try to avoid every module to have to import Module B explicitly. Thank you.

extending default theme chakra ui

I want to set default borderColor to all Input components but it doesn't work
This is my theme.js file:
import { extendTheme } from "#chakra-ui/react";
const config = {
initialColorMode: "light",
useSystemColorMode: false,
};
const theme = extendTheme({
config,
components: {
Input: {
borderColor: "teal",
},
},
});
export default theme;
Input is a multi-part component. You can figure out if the component you're trying to customise is single-part or multi-part by going to the docs for that component and clicking the View theme source button at the top of the page:
How to customise the theme: Docs
How to customise single-part and multi-part components: Docs (especially, how to customise multi-part components)
So in your case you need do something like this:
index.js :
import * as React from "react";
import { render } from "react-dom";
import { ChakraProvider, extendTheme } from "#chakra-ui/react";
import App from "./App";
const Input = {
variants: {
filled: () => ({
field: {
borderColor: "teal"
}
})
}
};
const theme = extendTheme({
components: {
Input
}
});
const rootElement = document.getElementById("root");
render(
<ChakraProvider theme={theme}>
<App />
</ChakraProvider>,
rootElement
);
App.js :
import * as React from "react";
import { Input } from "#chakra-ui/react";
export default function App() {
return <Input placeholder="extra small size" variant="filled" />;
}

Testing SVGR as React Component with Jest

Getting a warning when running test on svg component. It's not causing the test to fail but trying to get it cleaned up. Using SVGR to use svg files as react components. I believe the issue is Jest isn't able to see the svgr configuration in webpack, but not sure how to fix it.
Warning
console.error
Warning: <ReactComponent /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
at ReactComponent
at Icon (/code/common/javascript/components-2.0/lib/brand/Icon/index.tsx:9:11)
import { SvgIndexable } from "./Icon.types";
import { ReactComponent as ArrowRight } from "./svg/arrow-right.svg";
const iconNames: SvgIndexable = {
"arrow-right": ArrowRight,
}
export default iconNames
index.js
import React from "react";
import className from "classnames";
import { IconTypes } from "./Icon.types";
import iconNames from "./Icon.Components";
import styles from "./Icon.module.scss";
const Icon: React.FC<IconTypes> = (props: IconTypes): JSX.Element| null => {
const { id, name, extraClass, color = "black", size = "medium" } = props;
const iconClasses = className(styles[size], styles[color], extraClass);
const IconComponent = iconNames[name];
if (typeof iconNames[name] !== "undefined") {
return React.createElement(
iconNames[name],
{
id:id,
className:iconClasses,
"data-testid":`test__${id}-icon`,
},
null
);
} else {
return null;
}
};
export default Icon;
jest.config.json
"moduleNameMapper": {
"^#/(.*)$": "<rootDir>/lib/$1",
"components-2.0": "<rootDir>/__mocks__/components-2.0
"\\.(pdf|jpg|jpeg|png|gif|ico|xml|manifestjson|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "identity-obj-proxy",
"\\.svg$": "<rootDir>/__mocks__/components-2.0/svgrMock.js"
},
svgrMock.js
import * as React from "react";
export default "SvgrURL";
export const ReactComponent = "div";

Storybook not applying styles from .module.css file

I'm trying to use Storybook 6.1.20 for a very simple component in my project which uses Next.js, React and Typescript, however Storybook does not apply the styles that I have defined in my .module.css file. The styles are however applied when I start the project itself via npm run dev
This is my component that I want to display in Storybook (Rating.tsx):
import React from "react"
import ratingStyles from '../../../styles/Rating.module.css'
export interface RatingProps {
value: number
}
const Rating: React.FC<RatingProps> = ({value}) => {
return (
<span className={ratingStyles.text}>
{value}
</span>
)
}
export default Rating
The css file (Rating.module.css):
.text {
font-weight: 600;
font-size: 200px;
}
The story file (Rating.stories.tsx)
import React from 'react'
import { Story, Meta } from '#storybook/react';
import Rating, { RatingProps } from '../components/generic/Rating'
export default {
title: 'Rating',
component: Rating,
} as Meta
const Template: Story<RatingProps> = (args) => <Rating {...args}/>
export const FirstStory = Template.bind({})
FirstStory.args = {
value: 10
}

How to properly import/export components in React Native?

I'm trying to export initial component, but all the time I'm getting Invariant Violation error:
Is there any better way to export my HMAPP component and import it inside App.js?
Error image:
Error screen
Here is my App.js:
import HMAPP from './app/HMAPP';
export default HMAPP;
Here is my HMAPP component:
import { Provider } from 'react-redux';
import { persistStore } from 'redux-persist';
import { Navigation } from 'react-native-navigation';
import Mapbox from '#mapbox/react-native-mapbox-gl';
import { registerScreens } from './screens';
import store from './store/configureStore';
import { appInit, getInitialScreen } from './appInit';
import { handleErrorObject } from './lib/handleError';
Mapbox.setAccessToken('pkaeda324234');
const persistor = persistStore(
store,
null,
() => {
registerScreens(store, Provider);
appInit(store)
.then(() => {
const initialScreen = getInitialScreen(store.getState());
Navigation.startSingleScreenApp({
screen: {
screen: initialScreen,
},
passProps: {
persistor,
},
drawer: {
left: {
screen: 'DrawerMenuScreen',
},
},
appStyle: {
orientation: 'portrait',
},
});
})
.catch((error) => {
handleErrorObject('Error initializing app', error);
});
},
);
According to the docs of export and import, to externalize something inside one .js file, you need to use export. Once your module is exported, you can import him and use anywhere you want inside another .js files, for example.
So, in your HMAP.js file you'll need to export your const like this:
const persistor = persistStore( ... )
export default persistor;
and if you want to export more than one, you can export an object like this:
const persistor = persistStore( ... )
const persistor2 = persistStore2( ... )
export { persistor, persistor2 };
With your content exported, you can import it now on your App.js file:
import persistor from './app/HMAPP'; // use it when you exported with "default"
or
import { persistor1, persistor2 } from './app/HMAPP';
you could also import everything inside that file:
import * as persistors from './app/HMAPP';
Hope it helps someway.
In React Native, If you want to use your child component in other parent component then you have export that child component and import child component in parent component.
Else,
you declare your component with only class name, but in this way you can not use that component in any where.
Ex:
class Test extends React.Component {
}

Resources