Open maclockard opened 4 years ago
We don't get requests for this much, so going to leave it open and see if it reaches critical mass before proceeding.
Not a complicated feature obviously but we try not to add things directly to the library unless they're used often due to bundle size.
I'm sure you have a fix already, but my recommendation would be to make a HOC wrapper that does this prop translation for you.
What would this HOC wrapper look like? I know what it would look like for just making use of portalClassName
but unsure what it would look like for making use of both portalClassName
and className
on Dialog
.
I understand wanting to wait for critical mass, but one concern I would have is that folks won't really ask for this since the global style hack is 'good enough' for most people. However, the end result is that folks using styled components end up with more brittle styles that rely on global styles compared to if they used emotion or css modules instead.
@probablyup I have same problem as @maclockard It will be great if you support this possibility.
@probablyup I am facing the same problem
@probablyup I've run in to the same issue when using Reactour's API. It would be awesome to have a fix!
The same issue happens when using styled-components together with Webcomponents which expect class
attribute: <my-awesome-button class="big red">Click me!</my-awesome-button>
.
Just leaving a note here; I think the original issue suggests a solution, and personally, I don't really see a problem with it. I believe stylis
does support :global
and if we currently don't we could add it. That does open up other problems though, specifically that encapsulation is important, which is why previously, I believe, we've disabled it. Instead, what's much more desireable is to actually wrap a component like Dialog
and pass className
on as a different prop, hence enabling this using a small workaround.
However, what's much more important is to support the class
prop, which is an issue I've marked as duplicate for this one, since it's the same general concern, and we may want to opt for an explicit API instead of an automatic class
"switch".
I'm running into a situation that I don't see discussed here. I've got a component that accepts a wrapperClassName
, which gets applied to a wrapper element outside the input that gets the className
prop. So I can't use the attrs
work around, because my wrapper is not a child of the element that has className
. Emotion has a really nice solution to this (https://emotion.sh/docs/class-names) that doesn't require global styles, is there a way to do something similar with Styled Components?
@RobinClowers that's the same problem I described in the initial issue of the DOM tree not matching the React Component tree. Ideally this will be handled in the future by the more general API change @kitten is talking about.
For now, here is a hacky workaround I came up with for blueprint popover:
With some modification, should be able to be applied to your case as well.
Another example from #3582 based on react: Use "as" polymorphic prop to rename the HTML tag and get a better overview while using devTools, also in production mode. I end up using boilerplate code to map classname to class. It works but synchronize both needs more code and also the classnames stays twice (class + classname) within the HTML code / tag. It could be easier and less error prone with a configurable attribute target.
class MyComponent extends HTMLElement {
static get observedAttributes() {
return ['classname'];
}
attributeChangedCallback(name, oldValue, newValue) {
this.setAttribute('class', newValue);
}
}
window.customElements.define('x-button-y', MyComponent);
const Component = styled.div`
color: red;
`;
<Component as="x-button-y">some text</Component>
This issue was tagged with 6.0
but it looks like 6.0 was released without it. Curious if there are still any future plans to implement this (or if y'all are open to a PR for this)?
Would y'all be open to external contribution for this issue? This is very painful to workaround with 3rd party libraries and a major motivator of mine to potentially migrate away from styled component right now
I also would like this feature. I have a couple components that use a container element where I can pass containerClassName
and would love if I could remap the styled-component to target that prop instead of being the default className.
You can do this easily via styled(p => <Component yourCustomClassname={p.className} {...p} />)
fyi
You can do this easily via
styled(p => <Component yourCustomClassname={p.className} {...p} />)
fyi
While, yes it may be easy. It does add extra levels of complexity since now I need an extra wrapper component around anything that I want to do this too. A flag or some other way to change the target prop would save the extra wrapper component.
It is not an uncommon pattern for 3rd party component libraries to take multiple different css class props beyond just
className
. Currently styled-components only supports styling via theclassName
prop requiring hacky workarounds to make use of the other props.Take for example the
Dialog
component from the very popular React component library Blueprint. It has both aclassName
prop for the dialog proper and a prop for the surrounding portal componentportalClassName
. If you are using styled components you are unable to make use ofportalClassName
, and instead have to rely on global styles which is not preferable.In the past, a recommended workaround for the multiple class prop issue was to try to do something like the following:
This has a critical issue in that it makes an assumption about the DOM structure of
Dialog
, specifically that the elementportalClassName
is applied to is a descendant ofDialog
, which is not true in this case since the portal actually wrapsDialog
. In general, this workaround does not work any component that takes advantage of React's Portal API since there is no telling where in the DOM a portal element will actually render.Multiple class props is not an uncommon pattern for component libraries and pretty powerful css framework agnostic solution to styling multiple elements that works with vanilla css, emotion, css modules, etc. Adding support for this to styled-components would be helpful to those wishing to adopt styled-components but rely on 3rd party component libraries.
This issue had been previously discussed here: https://github.com/styled-components/styled-components/issues/1273, however, it did not adequately address some of the problems with assumptions of DOM structure.