๐ผ
36์ผ์ฐจ
Part 10. React ๋ก ์ผํ๋ชฐ ๋ง๋ค๊ธฐ (React ๊ธฐ๋ณธ)
Ch 5. React Component Styling
Ch 5. React Component Styling
๐ Style Loaders
// webpack.config.js
// import './App.css';
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
mode: 'icss',
},
}),
sideEffects: true,
},
// import styles from './App.module.css';
{
test: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
mode: 'local',
getLocalIdent: getCSSModuleLocalIdent,
},
}),
},
// import './App.scss';
// import './App.sass';
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
mode: 'icss',
},
},
'sass-loader'
),
sideEffects: true,
},
// import './App.module.scss';
// import './App.module.sass';
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
mode: 'local',
getLocalIdent: getCSSModuleLocalIdent,
},
},
'sass-loader'
),
},
๐ CSS
import './App.css';
๐ SASS
import './App.scss';
๐ CSS module => ์ ์ญ์ ์ผ๋ก ์ค์ผ๋์ง ์๊ฒ ์ฌ์ฉํ๋ค.
import './App.module.css';
https://create-react-app.dev/docs/adding-a-css-modules-stylesheet
{
App: "App_App__PsC3r"
App-logo-spin: "App_App-logo-spin__EtEZt"
header: "App_header__yz0SQ"
link: "App_link__o-ozp"
logo: "App_logo__Yh+D4"
}
(+ classnames)
$ npm i classnames
console.log(classNames("foo", "bar"));
console.log(classNames("foo", "bar", "baz"));
console.log(classNames({ foo: true }, { bar: false }));
console.log(
classNames(null, false, "bar", undefined, 0, 1, { baz: null }, "")
);
console.log(classNames(styles["button"], styles["loading"]));
// ./App.js
import styles from "./App.module.css";
import Button from "./components/Button";
function App() {
return (
<div className={styles["App"]}>
<header className={styles["header"]}>
<img src={logo} className={styles["logo"]} alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<Button>Button</Button>
</header>
</div>
);
}
export default App;
// ./components/Button.jsx
import React from "react";
import styles from "./Button.module.css";
import classNames from "classnames/bind";
const cx = classNames.bind(styles);
class Button extends React.Component {
state = {
loading: false,
};
render() {
const { loading } = this.state;
return (
<button
onClick={this.startLoading}
className={cx("button", { loading })}
{...this.props}
/>
);
}
startLoading = () => {
this.setState({
loading: true,
});
setTimeout(() => {
this.setState({
loading: false,
});
}, 1000);
};
}
export default Button;
// ./components/Button.module.css
.button {
background: transparent;
border-radius: 3px;
border: 2px solid palevioletred;
margin: 0 1em;
padding: 0.25em 1em;
font-size: 20px;
}
.loading {
border: 2px solid grey;
color: grey;
}
๐ Styled Components
$ npm i styled-components
// ./App.js
import StyledButton from "./components/StyledButton";
import styled from "styled-components";
import { createGlobalStyle } from "styled-components";
import StyledA from "./components/a";
const PrimaryStyledButton = styled(StyledButton)`
background: palevioletred;
color: white;
`;
const UppercaseButton = (props) => (
<button {...props} children={props.children.toUpperCase()} />
);
const MyButton = (props) => (
<button className={props.className} children={`MyButton ${props.children}`} />
);
const StyledMyButton = styled(MyButton)`
background: transparent;
border-radius: 3px;
border: 2px solid ${(props) => props.color || "palevioletred"};
color: ${(props) => props.color || "palevioletred"};
margin: 0 1em;
padding: 0.25em 1em;
font-size: 20px;
:hover {
border: 2px solid red;
}
::before {
content: "@";
}
`;
const GlobalStyle = createGlobalStyle`
button{
color: yellow;
}
`;
function App() {
return (
<div className="App">
<GlobalStyle />
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<StyledButton>๋ฒํผ</StyledButton>
<StyledButton primary>๋ฒํผ</StyledButton>
<PrimaryStyledButton>๋ฒํผ</PrimaryStyledButton>
<StyledButton as="a" href="/">
๋ฒํผ
</StyledButton>
<StyledButton as={UppercaseButton}>button</StyledButton>
<StyledMyButton>button</StyledMyButton>
<StyledMyButton color="green">button</StyledMyButton>
<StyledA href="https://google.com">ํ๊ทธ</StyledA>
</p>
</header>
</div>
);
}
export default App;
// ./components/StyledButton.jsx
import styled, { css } from "styled-components";
const StyledButton = styled.button`
background: transparent;
border-radius: 3px;
border: 2px solid palevioletred;
color: palevioletred;
margin: 0 1em;
padding: 0.25em 1em;
font-size: 20px;
${(props) =>
props.primary &&
css`
background: palevioletred;
color: white;
`}
`;
export default StyledButton;
// ./components/a.jsx
import styled from "styled-components";
const StyledA = styled.a.attrs((props) => ({
target: "_blank",
}))`
color: ${(props) => props.color};
`;
export default StyledA;
๐ React Shadow
https://developer.mozilla.org/ko/docs/Web/Web_Components
$ npm i react-shadow
// ./App.js
import root from "react-shadow";
const styles = `
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
p{
color: yellow;
}
`;
function App() {
return (
<root.div>
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
<style type="text/css">{styles}</style>
</root.div>
);
}
export default App;
// ./index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
ReactDOM.render(
<React.StrictMode>
<App />
<p>hello</p> // โญ
</React.StrictMode>,
document.getElementById("root")
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
- ๋จ์
- ๊ณตํต์ ์ผ๋ก๋ ์ฐ์ด๋ style ์ ๊ณ์ ๋ฐ๋ณต์ ์ผ๋ก ๋ฃ์ด์ค์ผ ํ๋ค.
- ์ธ๋ถ์ ๋ด๋ถ๊ฐ ์ฐจ๋จ๋์ด ์์ด, ์ธ๋ถ์์ ๊ฐ์ ๋ฐ์์ ์๋์ ์ผ๋ก ํํํ ๋ ์ ์ฝ์ด ์์ ์ ์๋ค.
๐ Ant Design
$ npm i antd
https://ant.design/components/calendar/
https://ant.design/components/icon/
$ npm install --save @ant-design/icons
https://ant.design/components/grid/#Row
// ./index.js
import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css"; // โญ
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
// ./App.js
import logo from "./logo.svg";
import "./App.css";
import { Calendar } from "antd";
import { GithubOutlined } from "@ant-design/icons";
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<GithubOutlined />
</p>
<Calendar />
</header>
</div>
);
}
export default App;