0

我正在为设计系统创建一个 React 库并styled-jsx用作 CSS-in-JS 解决方案。我们的 Web 应用程序由我们提供支持,Next.js并且我们可以高效地使用,styled-jsx并且因为 Vercel 也是背后的公司,styled-jsx我们考虑在我们的设计系统 React 库中使用这个库。

我已经按照这篇文章来引导 React 库,唯一的区别是使用styled-jsx而不是styled components.

问题在于这styled-jsx并没有将 CSS 的范围限制在组件级别。我创建了一个Text组件,它基本上是排版的包装器。这是我编写的组件的代码。

索引.tsx

/* eslint-disable no-use-before-define */
import React from 'react';

import { ThemeContext } from '../context/index';
import { RAVEN, SWAN } from '../colors/index';

type TextProps = {
    children: string;
    className?: string;
    textColor?: string;
    margin?: string;
    variant: string;
};

function Text(props: TextProps) {
    let className = 'text';
    switch (props.variant) {
        case 'h1': {
            className += ' text-heading-1';
            break;
        }
        case 'h2': {
            className += ' text-heading-2';
            break;
        }
        case 'h3': {
            className += ' text-heading-3';
            break;
        }
        case 'h4': {
            className += ' text-heading-4';
            break;
        }
        case 'h5': {
            className += ' text-heading-5';
            break;
        }
        case 'h6': {
            className += ' text-heading-6';
            break;
        }
        case 'body': {
            className += ' text-body';
            break;
        }
        case 'ol': {
            className += ' text-overline';
            break;
        }
        case 'button': {
            className += ' text-button';
            break;
        }
        case 'button2': {
            className += ' text-button-2';
            break;
        }
        case 'caption': {
            className += ' text-caption';
            break;
        }
        case 'st1': {
            className += ' text-subtitle-1';
            break;
        }
        case 'st2': {
            className += ' text-subtitle-2';
            break;
        }
        default: {
            className += ' text-body';
            break;
        }
    }

    return (
        <ThemeContext.Consumer>
            {(theme) => (
                <p className={`${className} ${props.className}`}>
                    {props.children}
                    <style jsx>
                        {`
                            .text {
                                width: fit-content;
                                margin: ${props.margin ? props.margin : '0'};
                                color: ${props.textColor
                                    ? props.textColor
                                    : theme === 'swan'
                                    ? RAVEN.EXTRA_DARK
                                    : SWAN.LIGHT};
                                font-family: 'Kanit', sans-serif;
                                text-transform: lowercase;
                            }
                            .text-heading-1 {
                                font-size: 61px;
                                font-weight: 400;
                                line-height: 92px;
                            }
                            .text-heading-2 {
                                font-size: 48.8px;
                                font-weight: 400;
                                line-height: 76px;
                            }
                            .text-heading-3 {
                                font-size: 39px;
                                font-weight: 400;
                                line-height: 60px;
                            }
                            .text-heading-4 {
                                font-size: 31.25px;
                                font-weight: 500;
                                line-height: 48px;
                            }
                            .text-heading-5 {
                                font-size: 25px;
                                font-weight: 600;
                                line-height: 40px;
                            }
                            .text-heading-6 {
                                font-size: 20px;
                                font-weight: 500;
                                line-height: 32px;
                            }
                            .text-body {
                                font-size: 16px;
                                font-weight: 400;
                                line-height: 24px;
                            }
                            .text-overline {
                                font-size: 12.8px;
                                font-weight: 500;
                                line-height: 20px;
                            }
                            .text-button {
                                font-size: 16px;
                                font-weight: 700;
                                line-height: 24px;
                            }
                            .text-button-2 {
                                font-size: 20px;
                                font-weight: 700;
                                line-height: 32px;
                            }
                            .text-caption {
                                font-size: 12.8px;
                                font-weight: 400;
                                font-style: italic;
                                line-height: 20px;
                            }
                            .text-subtitle-1 {
                                font-size: 16px;
                                font-weight: 500;
                                line-height: 24px;
                            }
                            .text-subtitle-2 {
                                font-size: 12.8px;
                                font-weight: 700;
                                line-height: 20px;
                            }
                        `}
                    </style>
                </p>
            )}
        </ThemeContext.Consumer>
    );
}

export { TextProps, Text };

现在我尝试在我们的 Web 应用程序中使用这个组件,这里是我使用它的页面的代码。

测试版.tsx

import React from 'react';
import { Container, Text, ThemeContext } from '@deriva-inc/davinci-react';

function BETA() {
    return (
        <ThemeContext.Provider value="raven">
            <Container>
                <Text margin="0" variant="h1">
                    h1. heading 1
                </Text>
                <Text margin="0" variant="h2">
                    h2. heading 2
                </Text>
                <Text
                    margin="0"
                    variant="h3"
                    className="heading-3-custom-1"
                    textColor="#FF0000"
                >
                    h3. heading 3
                </Text>
                <Text
                    margin="0"
                    variant="h3"
                    className="heading-3-custom-2"
                    textColor="#00FF00"
                >
                    h3. heading 3
                </Text>
                <Text
                    margin="0"
                    variant="h3"
                    className="heading-3-custom-3"
                    textColor="#0000FF"
                >
                    h3. heading 3
                </Text>
                <Text margin="0" variant="h4">
                    h4. heading 4
                </Text>
                <Text margin="0" variant="h5">
                    h5. heading 5
                </Text>
                <Text margin="0" variant="h6">
                    h6. heading 6
                </Text>
                <Text margin="0" variant="body">
                    body
                </Text>
                <Text margin="0" variant="ol">
                    overline
                </Text>
                <Text margin="0" variant="button">
                    button
                </Text>
                <Text margin="0" variant="button2">
                    button 2
                </Text>
                <Text margin="0" variant="caption">
                    caption
                </Text>
                <Text margin="0" variant="st1">
                    subtitle 1
                </Text>
                <Text margin="0" variant="st2">
                    subtitle 2
                </Text>
                <p className="text text-aayush">Aayush</p>
            </Container>
            <style jsx>
                {`
                    .text {
                        color: #00ff00;
                    }
                `}
            </style>
            <style jsx global>
                {`
                    main {
                        margin: 60px;
                    }
                    .heading-3-custom-1::selection {
                        background: #43bd99;
                    }
                    .heading-3-custom-2::selection {
                        background: #03865f;
                    }
                    .heading-3-custom-3::selection {
                        background: #409978;
                    }
                `}
            </style>
        </ThemeContext.Provider>
    );
}

export default BETA;

这是页面的呈现方式。

在此处输入图像描述

如您所见,我通过道具为所有三个标题 3 文本应用了不同的颜色,但在主题上下文中都以默认颜色呈现(即White)。当我调试页面时,我发现了这一点。

在此处输入图像描述

在此处输入图像描述

所以,我发现了问题。组件通过 prop 获取颜色,但由于 CSS 不限于组件,所有Text组件都在全局范围内呈现它们的 CSS,并且我们知道最后应用的 CSS 将按优先顺序排列,因此所有组件正在拿Text组件渲染的 CSS Subtitle 2。我不知道我在这里缺少什么或为什么它没有按预期工作。

我知道我们可以切换到styled-components,如果我们找不到解决这个问题的方法,我们就会这样做。任何帮助,将不胜感激。谢谢。

4

0 回答 0