-
Notifications
You must be signed in to change notification settings - Fork 187
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
Adding useImportant config #102
Conversation
This restores the behaviour previously expected by the tests
# Conflicts: # src/index.js
Thanks for the thorough PR description and tests! If I'm reading this right, this would be a major version change, because it changes the default to not use I haven't read through the code yet, but the idea of a global configuration like this is unsettling to me, especially because it means that import order becomes important. If a component author distributes a component that does It also means that doing a combination of Overall, I'm still much more comfortable with the |
@jlfwong correct, as written this would be a major / breaking API change, I was hoping this would become 1.0.0 as with configurable important behaviour, Aphrodite seems quite stable in terms of features and API. re: your concerns about global configuration, absolutely - component authors should never set To explain this, as the author of react-select I don't know whether it's going to be used in an environment where existing stylesheets might interfere with the component styles. So I can't make that call. If you use it on Khan Academy, you'll want So ideally I can use use Aphrodite to colocate my styles with my component, and add a link in my readme to Aphrodite's docs explaining how to configure the The alternative that's been suggested is each component author comes up with their own custom API and implementation to allow users to set whether the component uses re: a combination of Come to think of it, we could make it something you can set once and once only per runtime, and warn users if there could be conflicts (the way React warns you about certain things). If there's a valid use-case for some components forcing Seriously though, I think a better API for that than either changing Aphrodite's config or importing import React, { Component } from 'react';
import { StyleSheet, setConfig, importantify, css } from 'aphrodite';
class App extends Component {
render() {
return <div className={css(styles.red)}>This is red.</div>;
}
}
const styles = StyleSheet.create(importantify({
red: {
backgroundColor: 'red'
},
})); Behind the scenes, {
red: {
backgroundColor: 'red !important'
},
} The benefit to this approach is that the use of Finally, I want to call out vercel/hyper#99, which is a really interesting case for when Anybody building extension components for that project should simply need to understand |
I believe it's really like to have Aphrodite has so much going for it, but this is a huge thorn that needs to be addressed or it will drive users to other projects. |
I really appreciate the thorough discussion here, and don't at all want to disregard the effort in both the implementation here or the thought put into your comments, but I really don't think this is the right path. I'm really not sold on making this a global config. IMO, whether or not your component is using aphrodite should be an implementation detail that is not exposed to consumers. The ability to magically control whether or not all of a third party component's styles have Consider this scenario:
This PR is, IMO, trying to solve 3 problems at once, one of which I'm not convinced should be solved. First, it's trying to make it possible to set up styles without Second, it's trying to make it default to use styles without Third, it's trying to make it possible for things using your npm-installed component to control the I'm going to implement the |
Fair enough! I agree this is contentious and #104 is a nice non-breaking change that moves things forward. Adding that will work for projects nicely. I've got real concerns about being able to use Aphrodite in components (OSS) as well though, and without some kind of design change here Aphrodite's potentially harmful in that use case. We've been porting KeystoneJS / Elemental UI to it for a week now and it's been troubling working through a project of that complexity. Any chance we can get on a hangout or something to discuss rather than going back and forward here? I'd really like to figure out if Aphrodite's likely to move in a direction that works for scalable OSS or if I should be looking for a different thing. (No judgement, not here to tell you what your project needs to be or how to do it, just want to figure some stuff out before we invest in a use-case you may not be interested in or may not want to compromise other concerns for) |
I'd love to be on that call if I can be so presumptuous to invite myself 😄 I think a synchronous conversation about this would be helpful. |
If you want people to be able to override your styles, just use no-important in your component, right? That should match how you might distribute components without Aphrodite already. |
@spicyj breaks usage w/ existing stylesheets, same reason the important default was added in the first place. I like the concept of some way to aggressively raise precedence, it's valid, I see that as a build-step-like thing (similar to adding plugins to your css loaders in Webpack) i.e. using css-modules, your component does At the moment we're using LESS so people can modify the generated stylesheet pretty easily in the build step... we have no opinions about how the styles are actually added to the page, using Aphrodite changes that in a way that removes control from the component user. I've written a lot at this point though, like @kentcdodds said a sync conversation would be really beneficial. |
This is an alternative implementation to #41 based on our discussion there. Closes #25
Given the concepts that:
!important
to all generated styles is having a project with a legacy stylesheet that could clash with Aphrodite's classes!important
is applied to the style definitions!important
for all styles generated by Aphrodite in a project (and that this shouldn't be left to component authors to expose)I've implemented config that can be set on the
aphrodite
package itself, and a single option that controls whether to use important or not.So now to turn on
!important
, you would do the following once in your project (probably alongside the app entry point):This way, the setting will be applied consistently throughout the project regardless of the components being used, which I think is the best way to have this work.
The only downside I can see is that if someone uses a component styled by Aphrodite (without using Aphrodite in their project directly), and they needed to turn the
useImportant
setting on, they'd need to depend on aphrodite and include this somewhere in their project:Given that the alternative is for components to individually expose an API for this, I think it's a reasonable trade-off. (come to think of it, you could expose that as an API on a component package anyway, although I'm not sure it's a good idea...)
I've updated the existing unit tests, and added tests for the new functionality. I'm happy to update the Readme with documentation as well, but wanted to submit this for review first.
Overall I've tested this in my own projects and am really happy with how it works, two thoughts on the new config concept:
aphrodite.useImportant(true)
which wouldn't scale well if more options are added in the future.aphrodite.setConfig({ useImportant: true })
but the way I'd do that requires theObject.assign
polyfill in babel which isn't configured, so I left that out for simplicity.Finally, this implementation could behave unpredictably if more than one version of Aphrodite is included in a project... Given that's an edge case that React also has issues with, I think it's a reasonable trade-off.
Hope you like it!