ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TIL-2024.05.07 - React - 013. Styled Component - basic- 2
    > Frontend/React 2024. 5. 8. 07:07

     

     

    1. Coming From CSS

    1.1. Pseudoelements, pseudoselectors, and nesting

    -  사용하는 전처리기인 stylis는 자동으로 스타일을 중첩하는 SCSS와 유사한 구문을 지원합니다. 

    - 이 전처리를 통해 styled-components는 일부 고급 선택자 패턴을 지원합니다:

    - & 단일 앰퍼샌드는 컴포넌트의 모든 인스턴스를 가리킵니다. 이것은 넓은 범위의 재정의에 사용됩니다.

     

    1.1.1  단일 엠퍼센드 (&)

    - & 단일 앰퍼샌드는 컴포넌트의 모든 인스턴스를 가리킵니다. 이것은 넓은 범위의 재정의에 사용됩니다.

     

    예제 

    import styled from "styled-components";
    
    // single ampersand (&) refers to all instances of the component; it is used for applying broad overrides:
    const SingleAmpersand = () => {
        const Thing = styled.div.attrs((/* props */) => ({tabIndex: 0}))`
            color: blue;
    
            &:hover {
                // <Thing> when hovered
                // Pretty nice day today 제외 전체
                color: red;
            }
    
            & ~ & {
                // <Thing> as a sibling of <Thing>, but maybe not directly next to it
                // Dont' you think 에 해당
                background: tomato; 
            }
    
            & + & {
                // <Thing> next to <Thing>
                // How ya doing 에 해당
                background: lime; 
            }
    
            &.something {
                // <Thing> tagged with an additional CSS class ".something"
                // The Sun is Shining... 에 해당
                background: orange;
            }
    
            .something-else & {
                // <Thing> inside another element labeled ".something-else"
                // splendid에 해당
                border: 1px solid; 
                background: white;
            }
        `;
    
        return (
            <div>
                <Thing>Hello world!</Thing>
                <Thing>How ya doing?</Thing>
                <Thing className="something">The sun is shining...</Thing>
                <div>Pretty nice day today.</div>
                <Thing>Don't you think?</Thing>
                <div className="something-else">
                    <Thing>Splendid.</Thing>
                </div>
            </div>
        );
    };
    
    export default SingleAmpersand;

     

     

    1.1.2 더블 엠퍼센드(&&)

    - && 두 개의 앰퍼샌드는 컴포넌트의 인스턴스를 가리킵니다. 

    - 이것은 조건부 스타일 재정의를 수행하고 특정 컴포넌트의 모든 인스턴스에 스타일이 적용되지 않도록 하는 데 유용합니다.

     

     

    예제

    import styled, {css} from "styled-components";
    
    // double ampersand refers to an instance of the component;
    // this is useful if you're doing conditional styling overrides and don't want a style to apply to all instances of a particular component:
    const DoubleAmpersand = () => {
        const Input = styled.input.attrs({type: "checkbox"})``;
    
        const Label = styled.label`
            align-items: center;
            display: flex;
            gap: 8px;
            margin-bottom: 8px;
        `;
    
        const LabelText = styled.span`
            ${(props) => {
                switch (props.$mode) {
                    case "dark":
                        return css`
                            background-color: black;
                            color: white;
    
                            ${Input}:checked + && {
                                color: blue;
                            }
                        `;
                    default:
                        return css`
                            background-color: white;
                            color: black;
    
                            ${Input}:checked + && {
                                color: red;
                            }
                        `;
                }
            }}
        `;
    
        return (
            <div>
                <Label>
                    <Input defaultChecked/>
                    <LabelText>Foo</LabelText>
                </Label>
                <Label>
                    <Input/>
                    <LabelText $mode="dark">Foo</LabelText>
                </Label>
                <Label>
                    <Input defaultChecked/>
                    <LabelText>Foo</LabelText>
                </Label>
                <Label>
                    <Input defaultChecked/>
                    <LabelText $mode="dark">Foo</LabelText>
                </Label>
            </div>
        );
    };
    
    export default DoubleAmpersand;

     

     

    - 또한, 특별한 동작인 "우선 순위 부스팅"이 발생합니다.

    - 이는 혼합된 styled-components와 일반 CSS 환경에서 충돌하는 스타일이 있을 수 있는 경우 유용합니다

     

     

    예제

    import styled, {createGlobalStyle} from "styled-components";
    
    // && a double ampersand alone has a special behavior called a "precedence boost";
    // this can be useful if you are dealing with a mixed styled-components and vanilla CSS environment where there might be conflicting styles:
    const DoubleAmpersand2 = () => {
        const Thing = styled.div`
            && {
                color: blue;
            }
        `;
    
        const GlobalStyle = createGlobalStyle`
            div${Thing} {
                color: red;
            }
        `;
    
        return (
            <div>
                <GlobalStyle/>
                <Thing>
                    I'm blue, da ba dee da ba daa
                </Thing>
            </div>
        );
    };
    
    export default DoubleAmpersand2;

     

     

     


     

    2. Attaching Additional Props

    - 불필요한 래퍼를 피하기 위해 렌더링된 컴포넌트나 요소로 일부 props를 전달하는 경우 .attrs 생성자를 사용할 수 있습니다. 

    - 이를 사용하면 컴포넌트에 추가적인 props(또는 "속성")을 첨부할 수 있습니다.

    - 이렇게 하면 예를 들어 정적 props를 요소에 첨부하거나 React Router의 Link 컴포넌트에 activeClassName과 같은 서드파티 prop을 전달하고,  컴포넌트에 더 동적인 props를 첨부할 수도 있습니다.

    - .attrs 객체는 또한 컴포넌트가 받는 props를 전달하는 함수도 받습니다. 반환 값은 최종 props에 병합됩니다.

     

     

    예제

    import styled, {css} from "styled-components";
    
    const BasicUsage = () => {
    
        const Input = styled.input.attrs(props => ({
            // we can define static props
            type: "text",
            // and we can define dynamic ones
            $size: props.$size || "1em",
        }))`
            color: #BF4F74;
            font-size: 1em;
            border: 2px solid #BF4F74;
            border-radius: 3px;
    
            /* here we use the dynamically computed prop */
            margin: ${props => props.$size};
            padding: ${props => props.$size};
        `;
    
        return (<div>
            <Input placeholder="A small text input"/>
            <br/>
            <Input placeholder="A bigger text input" $size="2em"/>
        </div>);
    };
    
    export default BasicUsage;

     

     

     

    2.1 Overriding .attrs

    - styled 컴포넌트를 래핑할 때 .attrs가 가장 안쪽의 styled 컴포넌트부터 바깥쪽 styled 컴포넌트까지 적용됩니다.

    -  이는 각각의 래퍼가 중첩된 .attrs 사용을 재정의할 수 있도록 하여, 스타일 시트에서 이전 선언을 덮어쓰는 방식과 유사합니다.

     

     

    예제

    import styled, {css} from "styled-components";
    
    const OverridingAttrs = () => {
        const Input = styled.input.attrs((props) => ({
            type: 'text', $size: props.$size || '1em',
        }))`
            border: 2px solid #bf4f74;
            margin: ${(props) => props.$size};
            padding: ${(props) => props.$size};
        `;
    
        // Input's attrs will be applied first, and then this attrs obj
        const PasswordInput = styled(Input).attrs({
            type: "password",
        })`
            // similarly, border will override Input's border
            border: 2px solid aqua;
        `;
    
        return (<div>
            <Input placeholder="A bigger text input" $size="2em"/>
            <br/>
            {/* Notice we can still use the size attr from Input */}
            <PasswordInput placeholder="A bigger password input" $size="2em"/>
        </div>);
    
    };
    
    export default OverridingAttrs;

     

     

     

     

     

     

    댓글

Designed by Tistory.