"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2219],{21946:function(e,t,n){n.r(t),n.d(t,{_frontmatter:function(){return s},default:function(){return l}});var i=n(31461),a=(n(2784),n(94099)),o=["components"],s={title:"Motivation"},r={_frontmatter:s};function l(e){var t=e.components,n=(0,i.Z)(e,o);return(0,a.kt)("wrapper",Object.assign({},r,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"motivation"},"Motivation"),(0,a.kt)("p",null,"One of the primary motivations behind Theme UI is to make building themeable,\nconstraint-based user interfaces in React as simple and as interoperable as\npossible. This library builds upon years of work on various libraries, including\n",(0,a.kt)("a",{parentName:"p",href:"https://github.com/basscss/basscss"},"Basscss"),", ",(0,a.kt)("a",{parentName:"p",href:"https://tachyons.io"},"Tachyons"),", ",(0,a.kt)("a",{parentName:"p",href:"https://rebassjs.org"},"Rebass"),", ",(0,a.kt)("a",{parentName:"p",href:"https://styled-system.com"},"Styled System"),', and various other\ninternal style guides and design systems. While some of the ideas encapsulated\nwithin this library may seem familiar, the intent here is to combine modern CSS\ntooling into a single "mini-framework" with good guidance on how to fall into\nthe pit of success for creating white-label products, themed component\nlibraries, and even full websites.'),(0,a.kt)("h2",{id:"mdx"},"MDX"),(0,a.kt)("p",null,"MDX has, in my opinion, quickly become one of the best ways to render Markdown\nin React. The ability to render custom React components for any Markdown element\nwith the ",(0,a.kt)("inlineCode",{parentName:"p"},"MDXProvider")," is a very powerful API and has the potential to open up\nhow Markdown is leveraged in ways I think we'll continue to see evolve over the\ncoming years."),(0,a.kt)("p",null,"While the final rendered HTML ",(0,a.kt)("em",{parentName:"p"},"can")," be styled using global CSS or a wrapping\nelement with child selectors, there are certainly drawbacks to this approach,\nand they can lead to unexpected styling bugs when composing themes together.\nUsing the ",(0,a.kt)("inlineCode",{parentName:"p"},"MDXProvider")," to render custom styled components in MDX is a great way\nto avoid this, but the overhead for applying styles in this way can be a lot of\nwork, even with UI component libraries like Rebass or Material UI. Theme UI\nincludes the ",(0,a.kt)("inlineCode",{parentName:"p"},"theme.styles")," API as a light abstraction on top of this, that\nhopefully feels familiar to people from diverse backgrounds, even those with\nlittle or no experience using MDX."),(0,a.kt)("p",null,"For examples of previous explorations into this idea, see ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/rebassjs/mdx"},"Rebass MDX"),", ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/jxnblk/mdx-style"},"MDX\nStyle"),", and ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/jxnblk/mdx-blocks"},"MDX Blocks"),"."),(0,a.kt)("h2",{id:"the-css-and-sx-props"},"The ",(0,a.kt)("inlineCode",{parentName:"h2"},"css")," and ",(0,a.kt)("inlineCode",{parentName:"h2"},"sx")," Props"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"css")," prop is a powerful pattern for styling UI in React. It works like the\nbuilt-in ",(0,a.kt)("inlineCode",{parentName:"p"},"style")," prop, but it includes some of the best parts of the CSS\nlanguage, including media queries and pseudo-classes, and can be authored in\nnative JavaScript object literal syntax. The ",(0,a.kt)("inlineCode",{parentName:"p"},"css")," prop can be leveraged in a\nsimilar way to the ",(0,a.kt)("inlineCode",{parentName:"p"},"styled")," higher-order component, but also offers more\nflexibility when making one-off, context-specific stylistic changes. The ",(0,a.kt)("inlineCode",{parentName:"p"},"css"),"\nprop also avoids some of the\n",(0,a.kt)("a",{parentName:"p",href:"https://github.com/styled-components/styled-components/issues/439"},"pitfalls of mixing CSS properties with HTML attributes"),"."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"sx")," prop is a light abstraction on top of the ",(0,a.kt)("inlineCode",{parentName:"p"},"css")," prop that can serve as\na complete replacement and makes it easier to ensure you use values from your\nglobal ",(0,a.kt)("inlineCode",{parentName:"p"},"theme")," object."),(0,a.kt)("h2",{id:"why-object-literal-syntax"},"Why Object Literal Syntax"),(0,a.kt)("p",null,"For many, the choice between using object literal syntax for styles versus\ntagged template literals comes down to personal preference, but in the case of\nTheme UI, there are some fundamental reasons for using native JavaScript types\nfor styles."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"theme")," object itself is an object, and keeping styles in a similar format\nhelps reduce the API surface area. Using and parsing strings that represent\nembedded DSLs introduces overhead when mapping over key-value pairs. Theme UI\navoids this overhead for reasons related to performance, testing, and overall\nbundle size. For some of the ",(0,a.kt)("a",{parentName:"p",href:"https://facebook.github.io/jsx/"},"same reasons"),"\nthat React itself uses JSX (i.e. function calls) instead of tagged template\nliterals, Theme UI only includes support for authoring CSS with object literal\nsyntax. Additionally, using native JavaScript types has many other benefits that\nare outside of the scope of this document."),(0,a.kt)("h2",{id:"why-emotion"},"Why Emotion"),(0,a.kt)("p",null,"While there are many different solutions to handling CSS in JavaScript, Styled\nComponents and Emotion have become the most widely-used industry-standard\nlibraries. If you're building a custom component library, either Styled\nComponents or Emotion should suit your needs just fine."),(0,a.kt)("p",null,"For Theme UI, the decision was primarily based on these factors:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Emotion's implementation of the ",(0,a.kt)("inlineCode",{parentName:"li"},"css")," prop and the custom JSX pragma allows\nfor better integration with Theme UI's ",(0,a.kt)("inlineCode",{parentName:"li"},"sx")," prop"),(0,a.kt)("li",{parentName:"ul"},"The Emotion API includes more lower-level utilities, like ",(0,a.kt)("inlineCode",{parentName:"li"},"createEmotion")," that\ncould be leveraged when considering how multiple themes could be composed\ntogether"),(0,a.kt)("li",{parentName:"ul"},"Emotion's theming context is directly available in ",(0,a.kt)("inlineCode",{parentName:"li"},"@emotion/react"),", allowing\nthis library to leverage React's context API in different ways"),(0,a.kt)("li",{parentName:"ul"},"In the case of Theme UI internals, the ",(0,a.kt)("inlineCode",{parentName:"li"},"styled")," higher-order component utility\nis not necessarily the best API for creating components, and by not including\n",(0,a.kt)("inlineCode",{parentName:"li"},"@emotion/styled")," in the core package the bundle size is kept to a minimum –\ni.e. most of the same things can be achieved with the ",(0,a.kt)("inlineCode",{parentName:"li"},"css")," prop")),(0,a.kt)("h2",{id:"how-is-this-different-from-styled-system"},"How is this different from Styled System"),(0,a.kt)("p",null,"Theme UI's ",(0,a.kt)("inlineCode",{parentName:"p"},"sx")," prop was inspired by Styled System, and it uses the same theme\nspec that Styled System adheres to. Styled System is a much lower-level API that\nis not in any way coupled to React or Emotion. For example, Styled System works\nwith Node.js, Vue, Svelte, and many other libraries. Theme UI is intended to be\na higher-level abstraction specifically for use in React applications."))}l.isMDXComponent=!0}}]);
//# sourceMappingURL=component---src-pages-guides-motivation-mdx-7ba8ff797ed402a5c941.js.map