-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
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
[Core] Implements prepareStyles as composition of functions in muiTheme #2986
Conversation
@newoga Awesome work indeed 👍 👍 Thank you 😄 |
@@ -0,0 +1,3 @@ | |||
import flowRight from 'lodash.flowright'; |
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.
Do we need these 2 files? I mean it's gonna look like "API surface" to me. We can just require these whenever we want. and I'm not seeing a day we wouldn't use lodash, you know, since it's awesome 😁
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.
@alitaheri I had the same though and I'm open to removing these. The only library I thought we may one day replace these with is recompose, which ironically also uses lodash's compose for its implementation.
Either way I'm going to take it out compose.js
until we start using it in several places.
I wanted to talk to you two about merge.js
though. I'm thinking we should replace all mergeStyles
with one of the three:
- merge
- Object.assign
- destructuring
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 about lodash.assign
? It uses Object.assign if it's available. and it's faster than extend or merge imo. @oliviertassinari Thoughts?
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.
For the record I'd be happy with that 👍
I believe we should use assign for every style merging too. 👍 Thanks @newoga |
} | ||
|
||
// Left to right is the default. No need to flip anything. | ||
if (!muiTheme || !muiTheme.isRtl) return style; |
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 think that we don't need this line.
More generally, do we really need to provide the muiTheme
to the transformers?
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.
@oliviertassinari Let's not limit ourselves for now. We might want to add other things, or if this is gonna be documented, others might like to have access to the theme in their transformers. the impacts of having it is likely none. but excluding it completely might make it hard to put back (or maybe even impossible). besides! we might even be able to use this to pass down userAgent down the context and use it in the prefixer. Just saying 😁
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.
@oliviertassinari I agree we don't need the line but also agree with @alitaheri that we should possibly leave the muiTheme in the transformers for now.
The reason why the muiTheme
was there in the first place is because this ensureDirections
now names (rtl) was left untouched minus the name and merge implementation. I believe the rtl check could be removed and the warning show be moved top level too (these are currently listed as remaining task at the top of the PR)
7a409c9
to
dbb7bb5
Compare
I made some additional changes to this and rebased onto master so that it includes @oliviertassinari's auto-prefix changes. I decided to take passing in custom transformers out of the API for now. I think having that feature is now less urgent because the the two existing transformers (prefixing and RTL) can be disabled through If we want to explore making this publicly accessible, I think we can explore options in a new PR. The two key changes I made were the following: Moved the check for running
|
@newoga I see you have brainstormed the crap out of it 👍 👍 Really great job. I really like your approaches 👍 👍 🎉 Also, Does the polyfill also assign Symbols? |
if (!objB) return objA; | ||
return update(objA, {$merge: objB}); | ||
} | ||
export const mergeStyles = (...args) => Object.assign({}, ...args); |
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.
Do we really need to clone? I think it's an unnecessary allocation of an extra object. @oliviertassinari Thoughts?
Debatable though. I understand immutability, but since this is part of a chain, maybe it won't be all that necessary. Although I think the implications of cloning are a lot less than not. But still...
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 wish we didn't need this but it was breaking things when we weren't cloning. I think we have some situations in source where we may be passing in an undefined style, but I haven't been able to pinpoint everywhere it's happening yet. I just know calling simply Object.assign
broke the docs site and the tests.
I think it's worth going back and investigating though! I think the ideal would be that we shouldn't need to do 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.
Oh and one more point. the mergeStyles
is really going to be deprecated/removed when style-propable
is removed. This is kind of temporary.
I'm recommending we just reimplement the components to use the prepareStyles
from context directly, not from the style-propable
mixin, and anywhere we were calling mergeStyles()
we replace with Object.assign
. After that this can go away.
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.
Well, not having it is dangerous. Let it be, With memoization and proper optimization this doesn't matter at. So we better keep it like 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.
I agree, sounds good 👍
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'm recommending we just reimplement the components to use the prepareStyles from context directly, not from the style-propable mixin, and anywhere we were calling mergeStyles() we replace with Object.assign. After that this can go away.
Oh, right. So all the more reason to ignore what I said :D :D This is great as it is 😁
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.
Do we really need to clone?
I think that we don't have the choice regarding how we use the merge method in the source code.
I guess we could work on it but that out of the scope of this PR. It's perfect like this for now 👍.
That's an intersting question. I assumed so but assuming can be dangerous 😛. I'll have to investigate this more... |
This is the polyfill. unfortunately it doesn't support Symbols. but I think this wouldn't matter because if var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
}; |
import compose from 'lodash.flowright'; | ||
import warning from 'warning'; | ||
|
||
const CALLED_ONCE = Symbol('prepareStyles/calledOnce'); |
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.
Introducing a Symbol
will have some implication, have a look at the issues that this PR solve #2904.
I think that it's a breaking change.
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.
Mm, interesting. What do you and @alitaheri prefer? Use a regular string key or polyfill?
I wonder we're inevitably going to keep running into Symbol
issues because developers often assume it's "included".
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 think we should avoid polyfills for the time being. es6 has to become mainstream before we can use it libraries. I use every feature i can get my hands on in my application. but libraries are different 😁
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.
Okay did-flip
from before made more sense in the context of ensureDirection. Do you have a preference to what key we use? prepared: true
?
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.
What about mui-prepared: true
?
We should consider using a Symbol
again with v0.15.0.
dbb7bb5
to
4c3d1e0
Compare
@oliviertassinari @alitaheri Alright guys, I think we're close 😣 This has the following changes:
|
@newoga I think we have it! I like the current approach 👍. We will have to refactor a lot of code once it's merged. |
a704248
to
bd8d6ba
Compare
FYI just rebased onto master so this didn't get too far behind. I also decided to remove the re-implementation/migration of I think both PRs will be easier to understand when they're separated and these changes don't rely on one another so they don't need to be merged together. |
const CALLED_ONCE = 'muiPrepared'; | ||
|
||
export default function callOnce() { | ||
if (process.env.NODE_ENV === 'production') return; |
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.
What about englobing the all code inside the if
statement?
I'm not sure uglify is smart enough to remove unreachable code.
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.
Can do!
@newoga Yes, let's merge this 🎉 |
@oliviertassinari Sounds good! @alitaheri Do you want to give this a last look? |
@alitaheri or @mbrookes feel free to merge if you are happy with it. |
All good and awesome 👍 👍 JUst fix |
Signed-off-by: Neil Gabbadon <neil.gabbadon@emikra.com>
bd8d6ba
to
2f0d184
Compare
Thanks @alitaheri, much appreciated 😄 If all is green, this should be good to go. |
[Core] Implements prepareStyles as composition of functions in muiTheme
@newoga Awesome work, 133 messages in this PR 🚀! |
I know what a long one! Thanks guys! Big group effort 🎉 🎈 |
Really nice work. this was a big step indeed 👍 👍 |
The commit allows us to start using `Object.assign` for merging styles instead of this `mergeStyles` utility method. Chrome's currently has a bug in which its `Object.assign` implementation does not consistently or keys of merged objects. This sometimes led to styling bugs because some style properties rendered to the DOM in the wrong order (see mui#2986). This commit includes a babel transformation step that replaces all uses of `Object.assign` with the implementation at `simple-assign` and ignores the browser's native Object.assign implementation. Signed-off-by: Neil Gabbadon <neil.gabbadon@emikra.com>
The commit allows us to start using `Object.assign` for merging styles instead of this `mergeStyles` utility method. Chrome's currently has a bug in which its `Object.assign` implementation does not consistently or keys of merged objects. This sometimes led to styling bugs because some style properties rendered to the DOM in the wrong order (see mui#2986). This commit includes a babel transformation step that replaces all uses of `Object.assign` with the implementation at `simple-assign` and ignores the browser's native Object.assign implementation. Signed-off-by: Neil Gabbadon <neil.gabbadon@emikra.com>
The commit allows us to start using `Object.assign` for merging styles instead of this `mergeStyles` utility method. Chrome's currently has a bug in which its `Object.assign` implementation does not consistently or keys of merged objects. This sometimes led to styling bugs because some style properties rendered to the DOM in the wrong order (see mui#2986). This commit includes a babel transformation step that replaces all uses of `Object.assign` with the implementation at `simple-assign` and ignores the browser's native Object.assign implementation. Signed-off-by: Neil Gabbadon <neil.gabbadon@emikra.com>
The commit allows us to start using `Object.assign` for merging styles instead of this `mergeStyles` utility method. Chrome's currently has a bug in which its `Object.assign` implementation does not consistently or keys of merged objects. This sometimes led to styling bugs because some style properties rendered to the DOM in the wrong order (see mui#2986). This commit includes a babel transformation step that replaces all uses of `Object.assign` with the implementation at `simple-assign` and ignores the browser's native Object.assign implementation. Signed-off-by: Neil Gabbadon <neil.gabbadon@emikra.com>
This commit implements the
prepareStyles
function as a composition of functions that can be configured inmuiTheme
. It switches the./mixin/style-propable.js
implementation to use theprepareStyles
stored in context.@oliviertassinari @alitaheri
This is an initial implementation of the approach of storing
prepareStyles
in context. I cleaned up the code a bit, however like I said, I don't think we should document this until we've confirmed we're happy and the API is final (I already have some ideas of how to improve it, but it shouldn't have any real immediate benefit). It's also very well possible this will all go away when we adopt a new styling framework.Note: One minor difference I made is that the
getMuiTheme
function actually checks the computed theme forisRtl
before composing the functions. If it's false, it doesn't even bother including theensureDirections()
(renamed tortl()
) method. Edit: It now does this for theautoprefixer()
method based on theuserAgent
propertyRight now, the list of transformers can be overridden by adding the following property to the muiTheme. The following configuration would essentially disable the default behavior of always autoprefixing and callingRemoved customizing of transformers in this PR, other approaches have since been implemented.rtl()
whenisRtl
is equal totrue
.Remaining tasks:
rtl()
into something that runs before all style transformations are executed. DoneChangeNo longer necessaryrtl()
implementation to not care isisRtl
Future PR:
./mixins/style-propable.js
to getprepareStyles()
from context, not from importing it from./utils/style.js
../utils/style.js