using css-module with react? - reactjs

The React:
/**
* Created by pingfengafei on 16/11/28.
*/
import React from 'react';
import HeaderContainer from './HeaderContainer';
import NavContainer from './NavContainer';
import ContentContainer from './ContentContainer';
import CSSModules from 'react-css-modules';
import styles from './HomePageContainer.less';
class HomePageContainer extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="home-page-wrap-normal" styleName='home-page-wrap'>
<HeaderContainer />
<NavContainer />
<ContentContainer>
{this.props.children}
</ContentContainer>
</div>
);
}
}
export default CSSModules(HomePageContainer, styles, {allowMultiple: true});
The doom node :
The css style:
The webpack.config:
{
test: /\.(le|c)ss$/,
loader: "style!css?sourceMap&modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]!postcss!less"
}
I want to add css modules into my React project just like
instagram with react-css-modules.
But find 2 problems:
1: Can I partly using css-module?
The child nodes of HomePageContainer-home-page-wrap-Ql_jW all lose css style, and the same with home-page-wrap-normal.
It seems that I should replace the className with sytleName in the whole project. Is there any way that I can chose where use styleName and className with both showing the correct css style.
2:Can I open sourceMap in develop model?
The class with base64 is unreadable, I need a sourceMap connecting original class name with compiled class name.

To answer your first question, you can use :global inside your css/less file in order to load the style as normal css.
Please see this:
CSS Modules - exclude class from being transformed
To answer your second question, your class name in source map should be readable enough. You can change the following to make it even more readable:
localIdentName=[name]___[local]___[hash:base64:4]

Related

Connection between Bootstrap componments reactstrap and react.Component

I'm new to Rect. I'd like to ask perhaps a most basic question since I can't find the relavent documentation or a answer on Google.
Following is the first 3 lines of typical react code:
import React, { Component } from "react";
import {
Button,
Modal,
} from "reactstrap";
export default class CustomModal extends Component {
...
}
What is the connection between Bootstrap componments imported on the second line from reactstrap and the Component class in react(that is, react.Component)? Why a CustomModal subclass from react.Component instead of reactstrap.Modal? is react.Component a sort of abstract class and reactstrap.Modal concret class extending react.Component?
Basically, yes. You extend React.Component to create your own custom class-based React components. The others that you are importing are from libraries where the library author has already created the components. Note that you can also create custom function-based React components where you don't extend React.Component. I would recommend reading through the React.Component documentation.
To your question about how it relates to CustomModal, you would use Modal as a component within CustomModal. For example:
import React, { Component } from "react";
import {
Button,
Modal,
} from "reactstrap";
export default class CustomModal extends Component {
...
render() {
return <Modal />;
}
}
Note that this example is just to give you the idea of how to use an imported component in your own custom component. It is not necessarily how to use reactstrap.Modal itself.

Import CSS File to Styled Component

Is there a way to import a CSS file into a styled component?
One of my dependencies, React Quill Editor, is themeable by importing their CSS as a base and applying changes on top of it. All of my components are styled components, and I'd like to keep the CSS localized to the JS component rather than import the CSS as a 'global' style.
Right now I've take to copying their CSS into my own file in the following form.
I've written a brief example below.
/** editorCSS.js **/
import { css } from 'styled-components';
export default css`
/* copied CSS here */
.class-to-extend {
color: green;
}
`
/** EditorComponent.js **/
import styled from 'styled-components';
import ReactQuill from 'react-quill';
import editorCSS from './editorCSS';
const StyledReactQuill = styled(ReactQuill)`
${editorCSS}
/** Additional customization if necessary (e.g. positioning) */
`
export default StyledReactQuill;
`
I'd much rather import reference their css file in the scope of the styled component vs copying it.
If I do import ReactQuillCSS from 'react-quill/dist/quill.snow.css'; it will still apply my css globally due to the css-loader plugin.
Best,
Daniel
You could use raw-loader to load the quill.snow.css stylesheet and then include it in your styled component.
/** EditorComponent.js **/
import styled from 'styled-components';
import ReactQuill from 'react-quill';
import quillCSS from '!!raw-loader!react-quill/dist/quill.snow.css';
const StyledReactQuill = styled(ReactQuill)`
${quillCSS}
/** Additional customization if necessary (e.g. positioning) */
`
export default StyledReactQuill;
Per the raw-loader docs, you can use !! to prevent the styles being added globally via css-loader
Adding !! to a request will disable all loaders specified in the configuration
You can add a module rule to import styles locally from a CSS file into a styled component.
E.g. import all third party .css files from node_modules as raw string, others as usual:
// webpack.config.js
const config = {
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"], // load project styles via style-loader
exclude: /node_modules/,
},
{
test: /\.css$/,
use: ["to-string-loader", "css-loader"], // use to-string-loader for 3rd party css
include: /node_modules/,
},
// ...
],
},
// ...
}
Usage:
import styled from 'styled-components';
import ReactQuill from 'react-quill';
import ReactQuillCSS from 'react-quill/dist/quill.snow.css' // no custom webpack syntax
const StyledReactQuill = styled(ReactQuill)`
${ReactQuillCSS}
// ... other styles
`
Don't forget to install to-string-loader, if not used yet.
This has some advantages over #jonathanhculver's solution:
One central config file determines, how to process .css files
Follow Webpack recommendations:
Use module.rules whenever possible, as this will reduce boilerplate in your source code and allow you to debug or locate a loader faster if something goes south. (docs)
Avoid ESLint errors - take a look at the Codesandbox demo
css-loader can still resolve #import and url() for external CSS files, raw-loader won't
In order to achieve that you would need to use a different loader than css-loader. You could write an different loader which prepares it for styled-components rather than adding it to the global style sheet.
If you need css-loader, you would however need to define which css files are handled by it and which ones are loaded for styled-components, which makes it not really practical imho.
This is how I did:
Code
import React, { Component } from "react";
import ReactDOM from "react-dom";
import Styled from "styled-components";
const fetchStyles = () =>
fetch(
"https://gist.githubusercontent.com/bionicvapourboy/61d3d7a8546cb42e0e3194eb9505f48a/raw/5432218dd83320d53d1cbc2f230b81c765183585/style.css"
).then(response => response.text());
class App extends Component {
state = {
style: ""
};
componentDidMount() {
fetchStyles().then(data => this.setState({ style: data }));
}
Wrapper = () => Styled.div`
${this.state.style}
`;
render() {
const Wrapper = this.Wrapper();
return (
<div className="App">
<Wrapper>
<h1>Styled</h1>
</Wrapper>
<h1>Not Styled</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Demo
https://codesandbox.io/s/yw7xmx6x3x
As far as I know there is no way to import regular CSS just in scope. The way I have combined styled-components with CSS from libraries so far is to give your own styled component a className in the jsx.
const MyStyledComponent = styled(ComponentFromLibrary)`
color: red;
`;
// and in the render function
return (
<MyStyledComponent className="libraryClassname" />
);
Another example can be found in the official documentation:
https://www.styled-components.com/docs/advanced#existing-css
What you are proposing would work if editorCSS is just a string of the styles you want to apply to the component.
From my understanding styled-components is just essentially template literals anyways.
Your only issue should be that the imported css is defined as an object when you try to place it into your components css. Have you tried typecasting it to a string first?
/** EditorComponent.js **/
import styled from 'styled-components';
import ReactQuill from 'react-quill';
import editorCSS from './editorCSS';
const newCSS = editorCSS.toString();
export default Styled(ReactQuill)`
${newCSS}
`;

React - render imported .svg file

I need to render .svg files. I do not want to use dangerouslySetInnerHTML. I am able to successfully render an svg if I copy the svg contents directly and render it from a component.
However, this is not very reusable. I don't want to copy the contents from each .svg file. I would like to be able to import an svg file and pass that into my component that will then render the contents.
Here's what I have done so far, but it is not rendering my svg.
I have created a component that accepts an imported svg file, like this:
import React from "react";
class SvgComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
props.svg // this works if I copy my .svg contents here (<svg>....</svg>)
);
}
};
SvgComponent.propTypes = {
svg: React.PropTypes.string.isRequired,
};
export default SvgComponent;
And here is how I am using that component:
import mySvg from './images/mySvg.svg';
const Icon = (props) => {
return (
<svgComponent svg={mySvg} />
);
};
Icon.propTypes = {
icon: React.PropTypes.string.isRequired,
};
export default Icon;
This does not work -- it does not show my svg on the webpage, or even in the dom. When I inspect the page, all I see is an empty svgComponent:
<svgComponent />
Any help on getting .svg files to display in react would great!
I created a module to solve this problem. With it you can load the svg and manipulate its elements using JSX without having to paste the svg code.
Npm package:https://www.npmjs.com/package/react-samy-svg
Check an example on Glitch: https://fossil-transport.glitch.me
It's simple to use
<Samy path="path to your svg file">
<Proxy select="#Star" fill="red"/>
</Samy>
Whenever you need to change some SVG attribute just create a Proxy element and use the 'select' prop (accepts CSS selectors). All props set on Proxy will be forwared as attributes to the SVG element(s)

How to pass Markdown file as this.props in React?

I'm building a site in React using Redux, and my goal is to have a /pages folder full of markdown files that'll represent a pages content.
I have a React Container (smart) and a React Component (dumb) that'll be used to render the content. My thinking is that I'll import the markdown files to the parent container and pass them down to the child component to render them in the browser. I know I'll need to use something like markdown-it to convert the MD to HTML and maybe I'll need to use that in the child component.
My questions are:
1) How do I pass in markdown files from parent to child using this.props?
2) Am I on the right track? Is this the right way to go about it?
Here are my components:
Page Parent Container
import React from 'react'
import SamplePage from './../components/SamplePage'
export default class Page extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<section>
<SamplePage />
</section>
)
}
}
SamplePage Child Component
import React from 'react'
import { Link } from 'react-router'
export default class SamplePage extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<div className="page-container">
<Link to="/" className="previous-link">Go Back Home</Link>
// I want to render the MD here using {this.props.markdown}
</div>
)
}
}
A few things:
1) I recommend using a Markdown to JSX parser to keep your templating safe (otherwise you'd likely have to use dangerouslySetInnerHtml)
2) I'd run this parser during build time, so everything is already ready to go. If you're using webpack or browserify, you can add a custom loader/transformer function to look for *.md files being required and run it through the parser.
3) The parsed markdown is then simple JSX and can be required & dropped into your existing component as you've done above.

Unable to resolve some modules: "./style" when i import React-Toolbox component

I start making a new interface with react-toolbox. and this is just my first step and i face this problem. I got an message in my console:
Unable to resolve some modules: "./style" ...
i don't know why the style won't load. i also imported its component already.
here are some simple code :
import React from 'react';
import {Button} from 'react-toolbox';
class MyButton extends React.Component {
render() {
return (
<div>
<Button icon='bookmark' label='Bookmark' raised primary />
</div>
);
}
}
export default MyButton;
Thanks so much for your help.
You are getting this error because react-toolbox uses CSS Modules and you dont have the loaders to preprocess them.
You are going to need
webpack
css-loader
style-loader

Resources