1 Star 3 Fork 0

fisher / flexstyled

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

FlexStyled

FlexStyled is a simple runtime css-in-js library for react component

中文

  • zero dependencies.
  • runtime css generation.
  • support css variables.
  • support nested css.
  • support props dynamic css.
  • typescript support.

Open demo on CodeSandbox

Installation

pnpm add FlexStyled
# or
npm install FlexStyled
# or
yarn add FlexStyled

Usage

We plan to develop a Card component, which has a title attribute for displaying titles, a footer' attribute for displaying bottom content, and a children attribute as the content area of the card.

Basic Usage

import { styled } from "FlexStyled" 

export type  CardProps = React.PropsWithChildren<{
    title:string 
    footer?:string
  }>

export const Card = styled<CardProps>((props,{className})=>{
    const { title,children,footer} =props
    return (
      <div  className={className}>
        <div className="title">            
            {title}
        </div>
        <div className="content">{children}</div>
        <div className="footer">{footer}</div>
      </div>
    )
  },{  
    position:"relative",
    width:"100%",
    border:"1px solid #ccc",
    borderRadius:"4px" 
  })

-The above code will create a Card component, generate a style class (with a randomly generated name) for the style, and insert it into the head tag. -Then pass the className prop to the component, which will use this class name to apply the style.

You can find a CSS style similar to this in the head, where the className and style.id are both automatically generated. You can also specify styleId and className through the options parameter.

<style id="6rxqfu">
.sw6y3s4{
    position:relative;
    width:100%;
    border:1px solid #ccc;
    border-radius:4px;
}
</style>

Nested Style

Next, let's add styles to the title and footer of the Card component

export const Card = styled<CardProps>((props,{className})=>{
    const { title,children,footer} =props
    return (
      <div  className={className}>
        <div className="title">            
            {title}
        </div>
        <div className="content">{children}</div>
        <div className="footer">{footer}</div>
      </div>
    )},{  
      position:"relative",
      width:"100%",
      border:"1px solid #ccc",
      borderRadius:"4px",
      "& > .title":{
        fontSize:"20px",
        fontWeight:"bold",
      },
      "& > .footer":{
        borderTop:"1px solid #ccc",
        padding:"8px",
        textAlign:"right"
      }
  })

-We have added styles to the title and footer above. -Use the & symbol to represent the current parent element, similar to the syntax of nested CSS such as less and sass.

The style generated in head is as follows:

<style id="6rxqfu">
.sw6y3s4{
    position:relative;
    width:100%;
    border:1px solid #ccc;
    border-radius:4px;
}
.sw6y3s4 > .title{
    font-size:20px;
    font-weight:bold;
}
.sw6y3s4 > .footer{
    border-top:1px solid #ccc;
    padding:8px;
    text-align:right;
}
</style>

Dynamic Style

FlexStyled supports using props to dynamically set styles.

For example, we want the background color of the content card to be specified by the props.bgColor attribute.


export const Card = styled<CardProps>((props,{className,getStyle})=>{
    const { title,children,footer} =props
    return (
      <div  className={className} style={getStyle()}>
        <div className="title">            
            {title}
        </div>
        <div className="content">{children}</div>
        <div className="footer">{footer}</div>
      </div>
    )},{ 
      position:"relative",
      width:"100%",
      border:"1px solid #ccc",
      borderRadius:"4px",
      "& > .title":{
        fontSize:"20px",
        fontWeight:"bold",
      },
      "& > .footer":{
        borderTop:"1px solid #ccc",
        padding:"8px",
        textAlign:"right"
      },
      "& > .content":{
        padding:"8px",
        backgroundColor:(props)=>props.bgColor
      }
  })
  • The above code uses props.bgColor to dynamically set the background color of the content card.
  • In order to support dynamic properties, we need to use the getStyle function to get the dynamic style and inject it into the root element of the component.
  • The getStyle function returns a css style object that can be passed directly to the style attribute.
  • Any css property can use (props)=>{....} to dynamically generate CSS property values.

CSS Variables

FlexStyled supports using css variables.

We can use css variables in the root style declaration, and then use the setVar function to dynamically modify the css variable in the component.


export const Card = styled<CardProps>((props,{className,getStyle})=>{
    const { title,children,footer} =props
    const [primaryColor,setPrimaryColor] = React.useState("blue")
    return (
      <div className={className} style={getStyle({"--primary-color":primaryColor})}>
        </div>
        <div className="content">{children}</div>
        <div className="footer">{footer}</div>
      </div>
    )},{ 
      position:"relative",
      width:"100%",
      border:"1px solid #ccc",
      borderRadius:"4px",
      "--primary-color":"blue",
      "& > .title":{
        fontSize:"20px",
        fontWeight:"bold",
        color:"var(--primary-color)"
      },
      "& > .footer":{
        borderTop:"1px solid #ccc",
        padding:"8px",
        textAlign:"right"
      },
      "& > .content":{
        padding:"8px",
        backgroundColor:(props)=>props.bgColor
      }
  })
  • The above code uses css variables.
  • We declare a --primary-color css variable in the root style.
  • Then we use the --primary-color variable in the title style.
  • In order to modify the css variable, we need to introduce ref and pass ref to the root element, and then use the setVar function to modify the css variable.

Summary

FlexStyled is a very simple css-in-js library that can help you quickly encapsulate react components and support css variables and dynamic css properties.

  • By default, you only need to reference className in the component.
  • If you need to dynamically modify css variables, you need to introduce ref, pass ref to the root element, and then use the setVar function to modify css variables.
  • If you need to use props dynamic css properties, you need to use the getStyle function to get the dynamic css style and inject it into the root element.

creteStyle

styled function can also be used to create styles only and insert into head.

// card.style.ts

import { styled } from "FlexStyled"

// create style and insert into head
export default styled({ // 组件样式
      position:"relative",
      width:"100%",
      border:"1px solid #ccc",
      borderRadius:"4px",
      "--primary-color":"blue",
      "& > .title":{
        fontSize:"20px",
        fontWeight:"bold",
        color:"var(--primary-color)"
      },
      "& > .footer":{
        borderTop:"1px solid #ccc",
        padding:"8px",
        textAlign:"right"
      },
      "& > .content":{
        padding:"8px",
        backgroundColor:(props)=>props.bgColor
      }
})

// card.tsx
import cardStyle from "./card.style"

export default (props:CardProps)=>{
    return (
      <div className={cardStyle.className} style={cardStyle.getStyle({"--title-color":titleColor},props)}>
        <div className="title">            
            {props.title}
        </div>
        <div className="content">{props.children}</div>
        <div className="footer">{props.footer}</div>
      </div>
    )
  }

using createStyle.props to simplify the parameter passing, as follows:

 
export default (props:CardProps)=>{
    return (
      <div {...cardStyle.props()}>
          ...
      </div>
    )
  }

<div {...cardStyle.props({"--title-color":titleColor})}/>
<div {...cardStyle.props({"--title-color":titleColor},{props})}/>
<div {...cardStyle.props({"--title-color":titleColor},{props,className:"xxxxx xxxx"})}/>

Hook

FlexStyled also provides a hook useStyled to help you quickly encapsulate react components.

import { useStyle } from "FlexStyled"
export const Card2:React.FC<React.PropsWithChildren<CardProps>> = ((props:CardProps)=>{
    const { title } = props
    const [titleColor,setTitleColor] = useState("blue")
    const {className,getStyle } =  useStyle({
        // style 
    })
    return (
      <div className={className} style={getStyle({"--title-color":titleColor},props)}>
        <div className="title">            
            <span>{title}</span>
            <span className="tools"><button onClick={()=>setTitleColor(getRandColor())}>Change</button></span>
        </div>
        <div className="content">          
            {props.children}
        </div>
        <div className="footer">{props.footer}</div>
      </div>
    )
  })
  • The useStyle hook returns className and getStyle, which are used to inject style class names and dynamic styles.
  • The getStyle function returns a css style object that can be passed directly to the style attribute.
  • The useStyle hook supports passing options parameters to configure styleId and className.
  • The useStyle hook is the same as the styled function, the only difference is that the style sheet injected into the head will be automatically removed when the component is uninstalled.

Create Styled component

FlexStyled supports creating styled components, use html tag name.


import { styled } from "FlexStyled"

const MyButton = styled.div({
    color:"red",
    "&:hover":{
        color:"blue"
    }
})
  • You can also create other HTML tags, such as span, button, etc.

Performance

Due to the limitations of css-in-js, there may be performance issues. A recommended performance optimization method is to create all styles at once during the application's startup phase and insert them into the head, and then reference the styles in the component.

// styles.tsx
import { styled } from "FlexStyled"
export style1 = styled({...})
export style2 = styled({...})
export style3 = styled({...})

Options


// styled(<React.FC>,<styles>,<options>)

export interface StyledOptions{
    // The ID of the style sheet, if not specified, will be automatically generated
    styleId?:string                          
    // The generated class name, if not specified, will be automatically generated
    className?:string                        
}
MIT License Copyright (c) 2024 fisher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

css-in-js for react 展开 收起
JavaScript 等 4 种语言
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
JavaScript
1
https://gitee.com/zhangfisher/flexstyled.git
git@gitee.com:zhangfisher/flexstyled.git
zhangfisher
flexstyled
flexstyled
master

搜索帮助