{"id":26067712,"url":"https://github.com/zhangfisher/flexstyled","last_synced_at":"2025-07-19T19:35:28.193Z","repository":{"id":223073416,"uuid":"759220261","full_name":"zhangfisher/flexstyled","owner":"zhangfisher","description":"simple css-in-js for react ","archived":false,"fork":false,"pushed_at":"2024-08-16T03:54:38.000Z","size":383,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-28T14:03:11.490Z","etag":null,"topics":["css-in-js","css-in-react"],"latest_commit_sha":null,"homepage":"https://zhangfisher.github.io/repos#flexstyled","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zhangfisher.png","metadata":{"files":{"readme":"readme.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-18T01:16:15.000Z","updated_at":"2024-08-16T03:54:41.000Z","dependencies_parsed_at":"2024-02-18T05:19:23.555Z","dependency_job_id":"a07dd1db-925e-4338-ad50-dca8fd9422e5","html_url":"https://github.com/zhangfisher/flexstyled","commit_stats":{"total_commits":104,"total_committers":1,"mean_commits":104.0,"dds":0.0,"last_synced_commit":"bd98f7c55c03af800be9aa04427388c13ac5e678"},"previous_names":["zhangfisher/styledfc","zhangfisher/flexstyled"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/zhangfisher/flexstyled","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhangfisher%2Fflexstyled","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhangfisher%2Fflexstyled/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhangfisher%2Fflexstyled/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhangfisher%2Fflexstyled/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zhangfisher","download_url":"https://codeload.github.com/zhangfisher/flexstyled/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhangfisher%2Fflexstyled/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264482666,"owners_count":23615477,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css-in-js","css-in-react"],"created_at":"2025-03-08T21:45:39.617Z","updated_at":"2025-07-19T19:35:28.128Z","avatar_url":"https://github.com/zhangfisher.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FlexStyled\n\nFlexStyled is a simple runtime `css-in-js` library for react component\n\n[中文](https://zhangfisher.github.io/flexstyled/)\n\n- zero dependencies. \n- runtime css generation.\n- support css variables.\n- support nested css.\n- support props dynamic css.\n- typescript support.\n\n[Open demo on CodeSandbox](https://codesandbox.io/p/sandbox/FlexStyled-demo-x7w94w?layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522clstzj2mg0006356lkdcmsv3s%2522%252C%2522sizes%2522%253A%255B70%252C30%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522clstzj2mg0002356lq7y9whne%2522%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522clstzj2mg0003356lip4fhd1w%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522clstzj2mg0005356l6vsjkkfr%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B50%252C50%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clstzj2mg0002356lq7y9whne%2522%253A%257B%2522id%2522%253A%2522clstzj2mg0002356lq7y9whne%2522%252C%2522tabs%2522%253A%255B%255D%257D%252C%2522clstzj2mg0005356l6vsjkkfr%2522%253A%257B%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clstzj2mg0004356l6rts8s1f%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522UNASSIGNED_PORT%2522%252C%2522port%2522%253A0%252C%2522path%2522%253A%2522%252F%2522%257D%255D%252C%2522id%2522%253A%2522clstzj2mg0005356l6vsjkkfr%2522%252C%2522activeTabId%2522%253A%2522clstzj2mg0004356l6rts8s1f%2522%257D%252C%2522clstzj2mg0003356lip4fhd1w%2522%253A%257B%2522tabs%2522%253A%255B%255D%252C%2522id%2522%253A%2522clstzj2mg0003356lip4fhd1w%2522%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showShells%2522%253Atrue%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D)\n\n## Installation\n\n```bash\npnpm add FlexStyled\n# or\nnpm install FlexStyled\n# or\nyarn add FlexStyled\n```\n\n## Usage\n\nWe 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.\n\n\n### Basic Usage\n \n\n```tsx\nimport { styled } from \"FlexStyled\" \n\nexport type  CardProps = React.PropsWithChildren\u003c{\n    title:string \n    footer?:string\n  }\u003e\n\nexport const Card = styled\u003cCardProps\u003e((props,{className})=\u003e{\n    const { title,children,footer} =props\n    return (\n      \u003cdiv  className={className}\u003e\n        \u003cdiv className=\"title\"\u003e            \n            {title}\n        \u003c/div\u003e\n        \u003cdiv className=\"content\"\u003e{children}\u003c/div\u003e\n        \u003cdiv className=\"footer\"\u003e{footer}\u003c/div\u003e\n      \u003c/div\u003e\n    )\n  },{  \n    position:\"relative\",\n    width:\"100%\",\n    border:\"1px solid #ccc\",\n    borderRadius:\"4px\" \n  })\n\n```\n  \n-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.\n-Then pass the `className` prop to the component, which will use this class name to apply the style.\n\nYou 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 `id` and `className` through the `options` parameter.\n\n```html\n\u003cstyle id=\"6rxqfu\"\u003e\n.sw6y3s4{\n    position:relative;\n    width:100%;\n    border:1px solid #ccc;\n    border-radius:4px;\n}\n\u003c/style\u003e\n```\n\n### Nested Style \n\nNext, let's add styles to the `title` and `footer` of the `Card` component\n\n\n```tsx\nexport const Card = styled\u003cCardProps\u003e((props,{className})=\u003e{\n    const { title,children,footer} =props\n    return (\n      \u003cdiv  className={className}\u003e\n        \u003cdiv className=\"title\"\u003e            \n            {title}\n        \u003c/div\u003e\n        \u003cdiv className=\"content\"\u003e{children}\u003c/div\u003e\n        \u003cdiv className=\"footer\"\u003e{footer}\u003c/div\u003e\n      \u003c/div\u003e\n    )},{  \n      position:\"relative\",\n      width:\"100%\",\n      border:\"1px solid #ccc\",\n      borderRadius:\"4px\",\n      \"\u0026 \u003e .title\":{\n        fontSize:\"20px\",\n        fontWeight:\"bold\",\n      },\n      \"\u0026 \u003e .footer\":{\n        borderTop:\"1px solid #ccc\",\n        padding:\"8px\",\n        textAlign:\"right\"\n      }\n  })\n```\n\n-We have added styles to the `title` and `footer` above.\n-Use the `\u0026` symbol to represent the current parent element, similar to the syntax of nested CSS such as `less` and `sass`.\n\n\nThe style generated in `head` is as follows:\n\n```html\n\u003cstyle id=\"6rxqfu\"\u003e\n.sw6y3s4{\n    position:relative;\n    width:100%;\n    border:1px solid #ccc;\n    border-radius:4px;\n}\n.sw6y3s4 \u003e .title{\n    font-size:20px;\n    font-weight:bold;\n}\n.sw6y3s4 \u003e .footer{\n    border-top:1px solid #ccc;\n    padding:8px;\n    text-align:right;\n}\n\u003c/style\u003e\n```\n\n### Dynamic Style\n\n`FlexStyled` supports using `props` to dynamically set styles.\n\nFor example, we want the background color of the `content` card to be specified by the `props.bgColor` attribute.\n\n\n```tsx\n\nexport const Card = styled\u003cCardProps\u003e((props,{className,getStyle})=\u003e{\n    const { title,children,footer} =props\n    return (\n      \u003cdiv  className={className} style={getStyle()}\u003e\n        \u003cdiv className=\"title\"\u003e            \n            {title}\n        \u003c/div\u003e\n        \u003cdiv className=\"content\"\u003e{children}\u003c/div\u003e\n        \u003cdiv className=\"footer\"\u003e{footer}\u003c/div\u003e\n      \u003c/div\u003e\n    )},{ \n      position:\"relative\",\n      width:\"100%\",\n      border:\"1px solid #ccc\",\n      borderRadius:\"4px\",\n      \"\u0026 \u003e .title\":{\n        fontSize:\"20px\",\n        fontWeight:\"bold\",\n      },\n      \"\u0026 \u003e .footer\":{\n        borderTop:\"1px solid #ccc\",\n        padding:\"8px\",\n        textAlign:\"right\"\n      },\n      \"\u0026 \u003e .content\":{\n        padding:\"8px\",\n        backgroundColor:(props)=\u003eprops.bgColor\n      }\n  })\n```\n\n- The above code uses `props.bgColor` to dynamically set the background color of the `content` card.\n- 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.\n- The `getStyle` function returns a `css` style object that can be passed directly to the `style` attribute.\n- Any `css` property can use `(props)=\u003e{....}` to dynamically generate CSS property values.\n\n### CSS Variables\n\n`FlexStyled` supports using `css` variables.\n\nWe can use `css` variables in the root style declaration, and then use the `setVar` function to dynamically modify the `css` variable in the component.\n\n\n```tsx\n\nexport const Card = styled\u003cCardProps\u003e((props,{className,getStyle})=\u003e{\n    const { title,children,footer} =props\n    const [primaryColor,setPrimaryColor] = React.useState(\"blue\")\n    return (\n      \u003cdiv className={className} style={getStyle({\"--primary-color\":primaryColor})}\u003e\n        \u003c/div\u003e\n        \u003cdiv className=\"content\"\u003e{children}\u003c/div\u003e\n        \u003cdiv className=\"footer\"\u003e{footer}\u003c/div\u003e\n      \u003c/div\u003e\n    )},{ \n      position:\"relative\",\n      width:\"100%\",\n      border:\"1px solid #ccc\",\n      borderRadius:\"4px\",\n      \"--primary-color\":\"blue\",\n      \"\u0026 \u003e .title\":{\n        fontSize:\"20px\",\n        fontWeight:\"bold\",\n        color:\"var(--primary-color)\"\n      },\n      \"\u0026 \u003e .footer\":{\n        borderTop:\"1px solid #ccc\",\n        padding:\"8px\",\n        textAlign:\"right\"\n      },\n      \"\u0026 \u003e .content\":{\n        padding:\"8px\",\n        backgroundColor:(props)=\u003eprops.bgColor\n      }\n  })\n```\n\n\n- The above code uses `css` variables.\n- We declare a `--primary-color` `css` variable in the root style.\n- Then we use the `--primary-color` variable in the `title` style.\n- 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.\n\n### Summary\n\n`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.\n\n- By default, you only need to reference `className` in the component.\n- 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.\n- 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.\n\n\n## creteStyle\n\n`styled` function can also be used to create styles only and insert into head.\n\n```tsx\n// card.style.ts\n\nimport { styled } from \"FlexStyled\"\n\n// create style and insert into head\nexport default styled({ // 组件样式\n      position:\"relative\",\n      width:\"100%\",\n      border:\"1px solid #ccc\",\n      borderRadius:\"4px\",\n      \"--primary-color\":\"blue\",\n      \"\u0026 \u003e .title\":{\n        fontSize:\"20px\",\n        fontWeight:\"bold\",\n        color:\"var(--primary-color)\"\n      },\n      \"\u0026 \u003e .footer\":{\n        borderTop:\"1px solid #ccc\",\n        padding:\"8px\",\n        textAlign:\"right\"\n      },\n      \"\u0026 \u003e .content\":{\n        padding:\"8px\",\n        backgroundColor:(props)=\u003eprops.bgColor\n      }\n})\n\n// card.tsx\nimport cardStyle from \"./card.style\"\n\nexport default (props:CardProps)=\u003e{\n    return (\n      \u003cdiv className={cardStyle.className} style={cardStyle.getStyle({\"--title-color\":titleColor},props)}\u003e\n        \u003cdiv className=\"title\"\u003e            \n            {props.title}\n        \u003c/div\u003e\n        \u003cdiv className=\"content\"\u003e{props.children}\u003c/div\u003e\n        \u003cdiv className=\"footer\"\u003e{props.footer}\u003c/div\u003e\n      \u003c/div\u003e\n    )\n  }\n```\n\n\nusing `createStyle.props` to simplify the parameter passing, as follows:\n\n```tsx\n \nexport default (props:CardProps)=\u003e{\n    return (\n      \u003cdiv {...cardStyle.props()}\u003e\n          ...\n      \u003c/div\u003e\n    )\n  }\n\n\u003cdiv {...cardStyle.props({\"--title-color\":titleColor})}/\u003e\n\u003cdiv {...cardStyle.props({\"--title-color\":titleColor},{props})}/\u003e\n\u003cdiv {...cardStyle.props({\"--title-color\":titleColor},{props,className:\"xxxxx xxxx\"})}/\u003e\n\n```\n  \n## Hook\n\n`FlexStyled` also provides a hook `useStyled` to help you quickly encapsulate `react` components.\n\n \n```tsx\nimport { useStyle } from \"FlexStyled\"\nexport const Card2:React.FC\u003cReact.PropsWithChildren\u003cCardProps\u003e\u003e = ((props:CardProps)=\u003e{\n    const { title } = props\n    const [titleColor,setTitleColor] = useState(\"blue\")\n    const {className,getStyle } =  useStyle({\n        // style \n    })\n    return (\n      \u003cdiv className={className} style={getStyle({\"--title-color\":titleColor},props)}\u003e\n        \u003cdiv className=\"title\"\u003e            \n            \u003cspan\u003e{title}\u003c/span\u003e\n            \u003cspan className=\"tools\"\u003e\u003cbutton onClick={()=\u003esetTitleColor(getRandColor())}\u003eChange\u003c/button\u003e\u003c/span\u003e\n        \u003c/div\u003e\n        \u003cdiv className=\"content\"\u003e          \n            {props.children}\n        \u003c/div\u003e\n        \u003cdiv className=\"footer\"\u003e{props.footer}\u003c/div\u003e\n      \u003c/div\u003e\n    )\n  })\n```\n\n- The `useStyle` hook returns `className` and `getStyle`, which are used to inject style class names and dynamic styles.\n- The `getStyle` function returns a `css` style object that can be passed directly to the `style` attribute.\n- The `useStyle` hook supports passing `options` parameters to configure `id` and `className`.\n- 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.\n\n### Create Styled component\n\n`FlexStyled` supports creating styled components, use html tag name.\n\n```tsx\n\nimport { styled } from \"FlexStyled\"\n\nconst MyButton = styled.div({\n    color:\"red\",\n    \"\u0026:hover\":{\n        color:\"blue\"\n    }\n})\n\n```\n- You can also create other HTML tags, such as `span`, `button`, etc.\n\n\n## Performance\n\nDue 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.\n\n```tsx\n// styles.tsx\nimport { styled } from \"FlexStyled\"\nexport style1 = styled({...})\nexport style2 = styled({...})\nexport style3 = styled({...})\n```\n\n## Options\n\n\n```tsx\n\n// styled(\u003cReact.FC\u003e,\u003cstyles\u003e,\u003coptions\u003e)\n\nexport interface StyledOptions{\n    // The ID of the style sheet, if not specified, will be automatically generated\n    id?:string                          \n    // The generated class name, if not specified, will be automatically generated\n    className?:string                        \n}\n```\n\n ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhangfisher%2Fflexstyled","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzhangfisher%2Fflexstyled","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhangfisher%2Fflexstyled/lists"}