{"id":15603438,"url":"https://github.com/codemeasandwich/react-outline","last_synced_at":"2026-01-12T09:14:58.073Z","repository":{"id":57342131,"uuid":"97394514","full_name":"codemeasandwich/react-outline","owner":"codemeasandwich","description":"React inline styling framework to keep your makeup clean","archived":false,"fork":false,"pushed_at":"2019-01-18T10:34:11.000Z","size":237,"stargazers_count":1,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-30T22:42:16.352Z","etag":null,"topics":["inline-css","inline-styles","react","redux-outline"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codemeasandwich.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-16T16:03:54.000Z","updated_at":"2019-01-18T10:34:12.000Z","dependencies_parsed_at":"2022-09-16T03:01:36.104Z","dependency_job_id":null,"html_url":"https://github.com/codemeasandwich/react-outline","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/codemeasandwich/react-outline","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemeasandwich%2Freact-outline","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemeasandwich%2Freact-outline/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemeasandwich%2Freact-outline/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemeasandwich%2Freact-outline/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codemeasandwich","download_url":"https://codeload.github.com/codemeasandwich/react-outline/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemeasandwich%2Freact-outline/sbom","scorecard":{"id":296759,"data":{"date":"2025-08-11","repo":{"name":"github.com/codemeasandwich/react-outline","commit":"906d808d8e6a2db972ed252c446297f342b00c00"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-17T19:44:31.469Z","repository_id":57342131,"created_at":"2025-08-17T19:44:31.469Z","updated_at":"2025-08-17T19:44:31.469Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28337658,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T06:09:07.588Z","status":"ssl_error","status_checked_at":"2026-01-12T06:05:18.301Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["inline-css","inline-styles","react","redux-outline"],"created_at":"2024-10-03T03:03:20.582Z","updated_at":"2026-01-12T09:14:58.065Z","avatar_url":"https://github.com/codemeasandwich.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![react-outline logo](https://s3-eu-west-1.amazonaws.com/files.codemeasandwich.com/react-outline-logo2.png)\n\n\n## React-outline is a utility of managing your inline style.\n\nreact-outline was designed to more easly manage inline styles and better support server side rendering with complete styling.\n\n[![npm version](https://badge.fury.io/js/react-outline.svg)](https://badge.fury.io/js/react-outline)\n[![Build Status](https://github.com/codemeasandwich/react-outline/actions/workflows/publish.yml/badge.svg)](https://github.com/codemeasandwich/react-outline/actions/workflows/publish.yml)\n[![Coverage Status](https://coveralls.io/repos/github/codemeasandwich/react-outline/badge.svg?branch=v2.1.5)](https://coveralls.io/github/codemeasandwich/react-outline?branch=v2.1.5)\n[![GitHub issues](https://img.shields.io/github/issues/codemeasandwich/react-outline)](https://github.com/codemeasandwich/react-outline/issues)\n[![Bundle Size](https://img.shields.io/bundlephobia/minzip/react-outline)](https://bundlephobia.com/package/react-outline)\n[![Known Vulnerabilities](https://snyk.io/test/github/codemeasandwich/react-outline/badge.svg)](https://snyk.io/test/github/codemeasandwich/react-outline)\n\n\nFeathers:\n* Cleaner JSX markup (without the styles)\n* Easy creation of standered and custom element combining styles into the element\n   * Easer debugging of element with injected name attributes\n* Support a UI Color Palette\n* Dynamically add vendor prefixes\n* Cache calculated style\n* Named elements (Generate element mapped to name prop in DOM)\n\n# [Live Demo](https://s3.amazonaws.com/react-outline/index.html?down=0) / [Demo Source](https://github.com/codemeasandwich/react-outline/tree/master/example)\n\n---\n\n## Where to start?\n\n1. [Creating and applying a style](#creating-and-applying-a-style--basic-example-)\n2. [Generate a element from a style](#the-above-example-can-be-streamlined-using-the-tag-creater)\n3. [Combine style attribute](#combine-style-attribute)\n    1. [In a generated element](#you-can-combine-attribute-of-a-style-by-using-a-boolean-flag)\n    2. [using the style function](#the-attribute-flag-can-be-used-via-the-style-function)\n4. [Logic functions for run-time control of styles](#redux-outline-also-support-custom-function-to-have-run-time-control-over-your-styles)\n5. [Setting the options](#setting-the-options)\n    1. [setOptions](#-setOptions--function)\n    2. [withOptions](#-withOptions--function)\n6. [Using the options](#using-the-options)\n    1. [caching](#caching)\n    2. [colors](#colors)\n    3. [named](#named)\n7. [Comparisons](#comparisons)\n    1. [styled-components](#styled-components)\n\n### Quick Start\n\nThe simplest way to create styled components:\n\n```JS\nimport outline from 'react-outline'\n\n// Inline style schema - no nesting required!\nconst styles = outline({ \n  title: { fontSize: 25, backgroundColor: \"red\" } \n});\n\nconst Title = styles.title`div`\n\nexport default \u003cTitle\u003eHello World\u003c/Title\u003e\n// Renders: \u003cdiv style={{ fontSize: 25, backgroundColor: \"red\" }}\u003eHello World\u003c/div\u003e\n```\n\n### Creating and applying a style (Basic example)\n```JS\nimport outline from 'react-outline'\n\nconst styles = outline({ \n  title: { fontSize: \"25px\" } \n});\n\nexport default (props) =\u003e \u003cdiv style={styles.title()}\u003e{props.text}\u003c/div\u003e\n// Renders: \u003cdiv style={{ fontSize: \"25px\" }}\u003e\"hello\"\u003c/div\u003e\n```\n\n### Generate a styled element (Tag Creator)\n\n```JS\nimport outline from 'react-outline'\n\nconst styles = outline({ title: { fontSize: \"25px\" } });\n\nconst Title = styles.title`div`\n\nexport default (props) =\u003e \u003cTitle\u003e{props.text}\u003c/Title\u003e\n// Renders: \u003cdiv style={{ fontSize: \"25px\" }}\u003e\"hello\"\u003c/div\u003e\n```\n### Combine style variants\n\nUse `base` for default styles and add variants as sibling keys:\n\n```JS\nimport outline from 'react-outline'\n\nconst styles = outline({ \n  title: {\n    base: { fontSize: \"25px\" },\n    error: { color: \"#f00\" }\n  }\n});\n\nconst Title = styles.title`div`\n\n// Using a prop flag - cleanest!\nexport default \u003cTitle error\u003eSomething went wrong\u003c/Title\u003e\n// Renders: \u003cdiv style={{ fontSize: \"25px\", color: \"#f00\" }}\u003e...\u003c/div\u003e\n```\n\n**Alternative syntaxes:**\n```JS\n// Via style prop\n\u003cTitle style={{error: true}}\u003eError\u003c/Title\u003e\n\n// Via style function (inline)\n\u003cdiv style={styles.title({error: true})}\u003eError\u003c/div\u003e\n```\n\n### Style Functions (Runtime Control)\n\nAdd functions to compute styles dynamically at runtime:\n\n```JS\nimport outline from 'react-outline'\n\nconst styles = outline({ \n  content: { backgroundColor: \"gray\" },\n  cell: { fontSize: 10 }\n}, {\n  // 1 arg: receives the passed value\n  content: (count) =\u003e ({ height: `${count * 50}px` }),\n  \n  // 2 args: receives (baseStyle, passedValue)\n  cell: (style, important) =\u003e ({ \n    fontSize: style.fontSize + (important ? 5 : -5) \n  })\n});\n\nconst data = [\n  { name: \"foo\", important: true },\n  { name: \"bar\", important: false },\n  { name: \"baz\" }\n]\n\nexport default (\n  \u003cdiv style={styles.content(data.length)}\u003e\n    {data.map((item, i) =\u003e (\n      \u003cspan key={i} style={styles.cell(item.important)}\u003e{item.name}\u003c/span\u003e\n    ))}\n  \u003c/div\u003e\n)\n```\n\n**With generated elements** - the `style` prop becomes the function argument:\n\n```JS\nconst Group = styles.content`div`\nconst Cell = styles.cell`span`\n\nexport default (\n  \u003cGroup style={data.length}\u003e\n    {data.map((item, i) =\u003e (\n      \u003cCell key={i} style={item.important}\u003e{item.name}\u003c/Cell\u003e\n    ))}\n  \u003c/Group\u003e\n)\n```\n### Setting the options\n\nThere three mechanisms\n\n1. `setOptions` is used to set the default options of all calls to `outline(...)`\n2. `withOptions` is to custom the options for a specific instance of `outline(...)`\n3. Pass an options object as the 2nd parameters to outline\n\n#### \"setOptions\" function\n```JS\nimport {setOptions} from 'react-outline'\n        setOptions({caching:true,named:true})\n```\n\n#### \"withOptions\" function\n```JS\nimport {withOptions} from 'react-outline'\nconst outline = withOptions({caching:true,named:true})\n```\n\n### Using the options\n\n#### caching\n\n\u003e  **When enable, will case styled per element based on deep equal check**    \n\u003e  default to: `false`    \n\u003e  use: `{caching : true} ` (boolean)\n\n#### colors\n\u003e  **When enable, will case styled per element based on deep equal check**    \n\u003e  default to: `undefined`    \n\u003e  use: ` {colors : { red500:#F44336, indigo500:#3F51B5 }} ` (object)\n\n```JS\nimport {withOptions} from 'react-outline'\n\n// Using material-ui colors codes\nimport {colors} from 'material-ui/styles';\n\nconst outline = withOptions({colors})\n\nlet styles = {\n   base : {\n      foo:{\n        color:\"deepPurple900\"\n      }\n   }\n }\nstyles = outline(styles)\nexport default \u003cdiv style={styles.foo}/\u003e\n/*\n \u003cdiv style={{ backgroundColor:\"#311B92\" }} /\u003e\n*/\n```\n\n#### named\n\n\u003e  **Helpful for debugging. Will add a `name` attribute Dom element if you use a [generated element](#you-can-combine-attribute-of-a-style-by-using-a-boolean-flag)**   \n\u003e  default to: `true`    \n\u003e use: ` {named : true} ` (boolean)\n\n##### Using the named option\n\n```JS\n// Using the named option\nimport outline from 'react-outline'\n\nlet styles = {\n base : {\n      page:{\n        backgroundColor:\"#eee\"\n      }\n}\n\nstyles = outline(styles,{named:true}) // enable named elements\nconst Page = styles.page`div`         // create a div elemet with the 'page' style\nexport default Page                   // export the elemet\n\n/*\n \u003cdiv name=\"page\" style={{ backgroundColor:\"#eee\" }} /\u003e\n*/\n```\n\n### comparisons\n\n#### styled components\n\nI created react-outline becase of some shortcoming I found when trying to use styled-components in a new project. The problem's I addressed as:\n1) Elements where replaced and the new css class name was changed on each render.\nThis was a problem with using [animate.css](https://daneden.github.io/animate.css/) + [ReactCSSTransitionGroup](https://www.npmjs.com/package/react-addons-css-transition-group) -\u003e leaveActive.\nThe element would enter fine but just disappear immediately on leave.\n\nReact-outline supports ReactCSSTransitionGroup [Example](https://s3.amazonaws.com/react-outline/index.html?selectedKind=animate\u0026selectedStory=Animate.css\u0026full=0\u0026down=0\u0026left=1\u0026panelRight=0\u0026downPanel=kadirahq%2Fstorybook-addon-actions%2Factions-panel)\n\n2) You cant style exiting react of elements, only create new ones.\n\nWith React-outline you can create any element you what [Example](https://s3.amazonaws.com/react-outline/index.html?selectedKind=Basics\u0026selectedStory=Generate%20a%20element%20from%20a%20style\u0026full=0\u0026down=0\u0026left=1\u0026panelRight=0\u0026downPanel=kadirahq%2Fstorybook-addon-actions%2Factions-panel) or style an existing one [Example](https://s3.amazonaws.com/react-outline/index.html?selectedKind=animate\u0026selectedStory=Animate.css\u0026full=0\u0026down=0\u0026left=1\u0026panelRight=0\u0026downPanel=kadirahq%2Fstorybook-addon-actions%2Factions-panel)\n\n3) No vendor prefixes support.\n\nvendor prefixes support is provided by [inline-style-prefixer](https://www.npmjs.com/package/inline-style-prefixer) under the covers\n\n4) The style must be in a CSS string. Then makes moving existing inline style object to CSS is time time consuming\n\nCheckout any of the code here [examples](https://s3.amazonaws.com/react-outline/index.html?down=0)\n\n\n## Contributing\n\nFeature requests can be made using [Github issues](https://github.com/codemeasandwich/react-outline/issues)\n\nPull requests are totally encouraged and you are welcome to contribute to the development of `react-outline`. Please do raise an issue before making a pull request so as to determine if a particular feature is already being worked on or is currently out of the scope of this project.\n\n1. [Fork react-outline](https://github.com/codemeasandwich/react-outline/fork)\n2. Create a feature branch (git checkout -b my-new-feature)\n3. Write tests\n4. Ensure the code is covered\n5. Add story to the example storybook\n6. Commit your changes\n7. Push to your branch\n8. Make a pull request\n\n### Testing Process\n\nThe project requires **100% code coverage** before publishing to npm.\n\n- **New features** must include a Storybook example. These examples automatically become tests.\n- **Edge cases** are validated in `cornerCases.test.js` to ensure comprehensive coverage.\n- Run `npm run test:cover` to check coverage before submitting a PR.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodemeasandwich%2Freact-outline","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodemeasandwich%2Freact-outline","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodemeasandwich%2Freact-outline/lists"}