-
Notifications
You must be signed in to change notification settings - Fork 645
[RFC] Private API prototypes #362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This works, but props related to CSS are not getting removed from the rendered HTML
|
This pull request is automatically deployed with Now. |
|
How would we expose system props on "composite" components like |
|
@colebemis in this situation, instead of calling (probably with better naming though 😂 ) |
| borderColor: colors.gray[2], | ||
| borderRadius: theme.radii[1], | ||
| theme // set our theme to the default if no theme is provided | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These default props won't update if the consumer is using a custom theme, right? Is that a problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not as written, no. I think we still have to figure out what the "right" way is to do a default theme prop, if that's even a thing. 🙁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shawnbot this is setting the default theme here only if the user doesn't provide one, or are you talking about something else?
@colebemis - yeah, these values won't use the provided theme value it always defaults to our theme values... though I'm not sure if that's a huge problem or not? IMO the default values should be set to values from the Primer theme, and can always be overridden if you'd like to provide your own theme by providing a value for that prop. cc @broccolini
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@emplums I think the problem with this approach is that themeGet() doesn't work with it — but I could be wrong, and maybe it will magically work the way I expect it to with styled-components? IIRC, this wasn't working last I checked:
const Blue = styled.div`
background-color: ${themeGet('colors.blue.4')}
`
Blue.defaultProps = {theme}
// <Blue /> → no background-colorLast I remember looking at this, I suspected it was an issue with the theme not being available in context as opposed to props, but I might be totally off base. 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right we'd have to do it like this if we want to use themeGet since props aren't available outside the context of the component: 7e1c2c1
Doesn't feel too bad though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fwiw this isn't working currently in primer/components anyways 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I discovered something interesting... the reason this isn't working in primer/components (more accurately... the docs for primer/components) is because the theme prop for every component rendered in the docs is being overridden by the theme provided to Layout from mdx-docs... so the default is never set in any component because there is already a theme prop provided 🤦♀️
Two take-aways from this:
-
We should really have some sort of clean-ish dev environment so we aren't deciphering between primer/components issues and issues due to clashes with our docs stack 😂
-
I'd be keen to pair with you @shawnbot tomorrow to pull mdx-docs out and use your system for primer.style/design so that we're on the same page between repos and don't need to worry about theme clashes with
Layout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay, nice detective work! I think this is a simple fix: we can just use an <MDXProvider> in place of the Layout. Let me know if that works, and we can pair if need be!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right we'd have to do it like this if we want to use
themeGetsince props aren't available outside the context of the component: 7e1c2c1Doesn't feel too bad though?
@emplums and team, I read through this RFC PR, dig it. I apologize if you arrived at a conclusion or answer already regarding the themeGet utility, however, in the off chance that you're still exploring approaches, I have found that you can still leverage themeGet successfully in your custom Primer component when the theme provider is not defined, but the default theme prop is, as follows (ala styled-components)
...
themeGet
} from 'styled-system'
import theme from './theme'
...
border: ${props => themeGet('borders.1'), theme.borders[1])(props)};
...
Box.defaultProps = {
theme
}
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mannybecerra ah yes! We found a bug that was preventing the defaultProps from kicking in, which is why we were having issues with themeGet. We've resolved that and now it should work swimmingly! 🙌
renderPage
| ${FLEX_CONTAINER} | ||
| ${COMMON} | ||
| ${display} | ||
| ` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason we use template literal syntax instead of passing the system prop functions as arguments?
const Flex = styled.div`
${FLEX_CONTAINER}
${COMMON}
${display}
`
// vs
const Flex = styled.div(FLEX_CONTAINER, COMMON, display)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll be honest, I prefer the latter form for components that only use system props. However, I think there's a lot of value in consistency, and if folks need to add additional styles, it should be obvious how to do that. So leaving all of the components using tagged template literals might be good for that.
OTOH: in theory, there's a performance penalty for using template literals when we don't need them. Maybe we could compile those away with a babel plugin or something? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@colebemis @shawnbot hmm yeah honestly the only reason I left the syntax like that was because I'd previously had some CSS in there 😂 I like having consistent syntax but if there's a performance penalty then I don't think doing const Flex = styled.div(FLEX_CONTAINER, COMMON, display) is too confusing of a departure from the tagged template literal syntax
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Chiming in here 👋 since I know a little bit about styled-components 🙈: our Babel plugin automatically optimizes tagged template literals under the hood for perf. For example, by default babel-preset-env (or whatever the relevant Babel plugin is that's used under the hood) would turn this component:
const Simple = styled.div`
width: 100%;
`into this JS:
var _templateObject = _taggedTemplateLiteral(['width: 100%;'], ['width: 100%;'])
function _taggedTemplateLiteral(strings, raw) {
return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } }))
}
var Simple = _styledComponents2.default.div(_templateObject)which is done to be 100% spec-compliant, most of which is 100% irrelevant for writing styled components.
Our Babel plugin pre-empts that transformation and instead turns it into this much faster and smaller version ✨:
var Simple = _styledComponents2.default.div(['width: 100%;'])You can read more about that transformation in the docs, but TL;DR: if you use the Babel plugin it's not a problem since the two forms are basically identical perf-wise, if not then... use the Babel plugin! 😉
|
Closing this since I've started the refactor in #368 |
This PR is to test out different private API prototypes. This is very WIP and probably won't ship.
I'd like to test the following:
Removing
withSystemProps(and thussystem-components) and usingstyled-system+emotiondirectly in the component fileRemoving
withSystemPropsand thussystem-components) and usingstyled-system+styled-componentsdirectly in the component fileRefactor a fully CSS in JS component with this method
BorderBox: https://github.com/primer/components/pull/362/files#diff-f4feaf115f7acdc3f36c8bd1fa501ff5
Box: https://github.com/primer/components/pull/362/files#diff-2ce98dcc0818477f331e426d8528ea2e
Refactor a component that uses Primer CSS with this method
Button: https://github.com/primer/components/pull/362/files#diff-0667e450e6d5ec59d1a58311f568c7f5
Refactor a component with nested components in it with this method
Flex: https://github.com/primer/components/pull/362/files#diff-536fc7306c4dbbc05c91c9d209661a6f
... more to come
Baseline Success Criteria:
styled(Box))styled-systemisprop in the public API to easily change rendered tagthemeGetor something similar to use values from a custom provided themeNice to have: