PJCHENder 未整理筆記

[Note] styled-component 學習筆記

2018-12-27

[Note] styled-component 學習筆記

@(React)[npm, package, react]

Styled Components

如果有第三方或自己寫的元件(components)想要變成 styled components 的話,只需在原本自己的元件上加上 className,讓 styled-components 可以為它添加 class 名稱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/ This could be react-router-dom's Link for example
const Link = ({ className, children }) => (
<a className={className}>
{children}
</a>
);

const StyledLink = styled(Link)`
color: palevioletred;
font-weight: bold;
`;

render(
<div>
<Link>Unstyled, boring Link</Link>
<br />
<StyledLink>Styled, exciting Link</StyledLink>
</div>
);

Styling any components @ styled-components

Props

如果你要 styled 的是:

  • 是 一般的 HTML 元素(例如 styled.div),styled-components 會把所有已知合法的 HTML Attributes 當成 props 傳入
  • 是 React 元件(例如,styled(MyComponent)),那麼 styled-components 會把所有的 props 當成 props 傳入**。

如果是一般的 HTML 元素,想要加入非正規的 HTML 屬性時,需要使用 .attrs() 方法。

attrs

透過 .attrs() 方法,除了自定 HTML 屬性放到 HTML 元素上,還可以使用動態的屬性(dynamic attributes)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const Input = styled.input.attrs({
// 這裡可以定義合法或自訂的 HTML attributes
type: "password",
foo: 'bar',

// 也可以動態定義 HTML 屬性
margin: props => props.size || "1em",
padding: props => props.size || "1em"
})`
color: palevioletred;
font-size: 1em;

/* 在這裡可以直接拿動態的屬性來用 */
margin: ${props => props.margin};
padding: ${props => props.padding};
`;

render(
<div>
<Input placeholder="A small text input" size="1em" />
<br />
<Input placeholder="A bigger text input" size="2em" />
</div>
);

Attaching Additional Props @ styled-components

Animations

在 CSS Animations 中 @keyframes 通常不會被縮限在一個元件中,但使用上卻又不希望它跑到全域造成命名衝突,因此在 styled-components 中有一個 keyframes 的 helper,讓我們可以使用同一個 @keyframes 但又不會有命名衝突:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import styled, { keyframs } from 'styled-components';

// 建立 keyframes
const rotate = keyframes`
from {
transform: rotate(0deg);
}

to {
transform: rotate(360deg);
}
`;

// 使用定義好的 rotate keyframes
const Rotate = styled.div`
display: inline-block;
animation: ${rotate} 2s linear infinite;
padding: 2rem 1rem;
font-size: 1.2rem;
`;

render(
<Rotate>&lt; 💅 &gt;</Rotate>
);

Theme

在 styled-components 中還提供 <ThemeProvider> 這個 wrapper 元件,這個元件透過 context API 可以把內層的所有 React 元件都提供 theme props。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

// Define our button, but with the use of props.theme this time
// STEP 3:在原本的 React Component 中,可以透過 props.theme 取得先前定義好的物件
const Button = styled.button`
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border-radius: 3px;

/* 根據 theme.main 顯示顏色 */
color: ${props => props.theme.main};
border: 2px solid ${props => props.theme.main};
`;

// 對於沒有綁定的可以使用預設值
Button.defaultProps = {
theme: {
main: "palevioletred"
}
}

// STEP 1: 定義要帶入 theme props 的物件
const theme = {
main: "mediumseagreen"
};

// STEP 2: 透過 <ThemeProvider> 把物件帶入 theme props 中
render(
<div>
<Button>Normal</Button>

<ThemeProvider theme={theme}>
<Button>Themed</Button>
</ThemeProvider>
</div>
);

VSCode

在搭配 VSCode 使用 styed-component 時,若遇到無法 “Fold All” 該程式碼區塊時,可以加上以下設定:

1
2
3
4
5
6
7
8
9
10
11
12
"[javascript]": {
"editor.formatOnSave": false,
"editor.formatOnPaste": false,
"editor.renderWhitespace": "all",
"editor.foldingStrategy": "indentation",
},
"[javascriptreact]": {
"editor.formatOnSave": false,
"editor.formatOnPaste": false,
"editor.renderWhitespace": "all",
"editor.foldingStrategy": "indentation"
},

參考文章

Tags: React

掃描二維條碼,分享此文章