-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
RFC: Theming in the future #973
base: main
Are you sure you want to change the base?
Conversation
docs/theming.md
Outdated
|
||
### Global Namespace | ||
|
||
Since there’s was a single object which contained the theme, if a component from npm or somewhere wanted to use theming, it had to choose a unique name store it’s theme in which meant name conflicts could occur. By directly using the Context API, this problem doesn't exist. |
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.
This shouldnt be relevant point here because it refers to legacy context and it's not a problem with new context APi.
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.
It's relevant to the current theming solution. There's only a single object in the current theming API which means libraries have to namespace.
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.
oh, i have kinda skipped the part where you mention libraries built on top of emotion 😅
docs/theming.md
Outdated
|
||
### Testing | ||
|
||
To test components that used the previous theming API, either a default theme has to be provided with defaultProps or a ThemeProvider has to be wrapped around every component which could get really inconvenient. By providing a default value when the theme is created, components can just be rendered. |
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 don't feel strongly about this one - you might improve DX for testing here, but you deteriorate (to some extent) DX for writing components
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.
How does it deteriorate DX for writing components?
I agree that this isn't the strongest point though, it was part of a point about people using theming when it's not really necessary but it didn't make a lot of sense so I changed it to this. It's kind of more about having to provide a default value so the component can be rendered anywhere without requiring a certain ancestor.
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.
How does it deteriorate DX for writing components?
Current way of using theme is way more ergonomic (in my opinion) than having to manually use theme context
docs/theming.md
Outdated
|
||
To test components that used the previous theming API, either a default theme has to be provided with defaultProps or a ThemeProvider has to be wrapped around every component which could get really inconvenient. By providing a default value when the theme is created, components can just be rendered. | ||
|
||
### Over-subscription |
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.
Preferring css variables for theming this also is not quite a problem, right?
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.
Oops, I didn't finish this bit. It's meant to talk about every styled component having to subscribe to the theme even if it doesn't use it.
docs/theming.md
Outdated
/** @jsx jsx */ | ||
import { jsx } from '@emotion/core' | ||
import { useTheme } from './theme' | ||
|
||
let Button = props => { |
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.
this recommendation suffers from shouldForwardProp
problem, which really gets annoying long term from DX perspective
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.
Maybe this example shouldnt mention button
but rather a composite component
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.
Why? Use rest spread if you have a prop you want to use that shouldn't be passed down.
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.
IMO, it's much better than styled in this regard because there's a native language feature for stopping certain props from being forwarded rather than having to learn a library-specific API.
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.
right, ive misjudged the example by not thinking about it too much and having styled API with interpolations in mind, css prop doesnt suffer from this
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.
We should probably dedicate a page on the docs dedicated to mapping solutions to "known" apis like withComponent
, shouldForwardProp
, etc. We should also show how easy it is to add further functionality to components this way. We could link to that page from here.
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.
This is great. Great work on these docs.
docs/theming.md
Outdated
### Global Namespace | ||
|
||
Since there was a single object which contained the theme, if a component from npm or somewhere wanted to use theming, it had to choose a unique name store it’s theme in which meant name conflicts could occur. By directly using the Context API, this problem doesn't exist. | ||
|
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.
An example here would emphasize this point because even though it is a great one, it can be hard to visualize.
docs/theming.md
Outdated
/** @jsx jsx */ | ||
import { jsx } from '@emotion/core' | ||
import { useTheme } from './theme' | ||
|
||
let Button = props => { |
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.
We should probably dedicate a page on the docs dedicated to mapping solutions to "known" apis like withComponent
, shouldForwardProp
, etc. We should also show how easy it is to add further functionality to components this way. We could link to that page from here.
I totally agree with this, this is a great direction. My only request would be that emotion ships with the following as default: import { createContext, useContext } from 'react'
const ThemeContext = createContext({})
export const ThemeProvider = ThemeContext.Provider
export const useTheme = () => useContext(ThemeContext) That way for the simple cases we can just Otherwise it just adds to the boilerplate. Right? |
💥 No ChangesetLatest commit: d8a5f4a Merging this PR will not cause any packages to be released. If these changes should not cause updates to packages in this repo, this is fine 🙂 If these changes should be published to npm, you need to add a changeset. Click here to learn what changesets are, and how to add one. Click here if you're a maintainer who wants to add a changeset to this PR |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit d8a5f4a:
|
colors: { | ||
primary: 'hotpink' | ||
let Button = styled.button(() => { | ||
let theme = useTheme() |
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.
This usage and the below usage trigger errors in the latest React.
Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
This is the line it errors on
const Card = styled.div`
background-color: ${() => useTheme().palette.white}; /* Error */
`
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.
@stramel have you tried to use this with emotion 10 or 11? It can only work with the latter.
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.
Oh let me try! Thank you for the quick reply!
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.
@Andarist I'm running it inside Docz v2 using @emotion/styled
and @emotion/core
on version 11.0.0-next.9
.
When starting the project it complains because it can't find @emotion/styled-base
.
ERROR #98123 WEBPACK
Generating SSR bundle failed
Can't resolve '@emotion/styled-base' in 'Projects/libs/atoms/src/lib/Button'
so I installed @emotion/styled-base
version v11.0.0-next.3
and it is telling me i need to use @emotion/styled
?
When I tried the v10
version of @emotion/styled-base
it obviously failed... 😞
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.
Seems like maybe you have 2 versioms of emotion in your node modules for some reason or that you are using v10 of our babel plugin. @emotion/styled-base
has been removed in v11 in favor of @emotion/styled/base
.
If you prepare a runnable repro case then I could take a look at it.
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.
@Andarist Looks like you were correct. Just tried it in my Next.js app with v11 and no errors. Doing some debugging...
yarn why @emotion/core
and yarn why @emotion/styled
both result in v10 and v11 because Docz and the gatsby docz theme both use v10
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.
Any suggestions how to fix it?
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 filed an issue on docz asking for a bumping to v11 but I'm not sure what the workaround would be. doczjs/docz#1335
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.
Thank you @stramel! Anyone know the expected release date of v11?
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 can't promise anything, but hopefully within a month. We have most of the things done, some final touches left, but this is a work we are doing in our free time so there is also a possibility that this will take some more time.
@mitchellhamilton I think the work on theming in v11 is better than this approach of stripping it out? Thoughts on closing this? |
We dont intend to remove builtin theming but some of the problems with it were nicely outlined here. We should „compile” those parts into docs and recommend using builtin theming only when building apps while using custom theme approach where developing libraries on top of emotion |
I wrote my thoughts on what I think theming should look like with Hooks as documentation so read it on GitHub or on the deploy preview.
I think this is what we should primarily recommend because I’m not sure about the practicality of #887 in the real world and I’m not sure if the trade off in terms of dynamicism will really translate to an important performance improvement in the real world. I'm thinking of publishing it outside of the emotion packages and maybe trying it in a real project to see how well it works and then think about making it an official emotion package.
We should also absolutely keep on supporting the current theming API for at the absolute minimum, v10 but not provide the theme to the css prop, Global or ClassNames.