I'm using react-select in my application and it is been working great until I hit this situation.
I have wrapped my react application as a shadow-DOM component to isolate styles from other applications. After this change react-select does not get any styles applied.
As per my analysis, react-select uses emotion library to build dynamic css and these styles are being added to document>head section. Since my application is a Shadow-DOM wrapped application, these external styles are not accessible to react-select.
I can see option to write my custom styles but that is very tidies to write all styles and upgrades will become unmanageable. Please suggest a solution for this case.
I've received a suggestion from emotions library group to use a custom container.
https://github.com/emotion-js/emotion/issues/388
Could not achieve this. Any help on this is greatly appreciated.
I have the same problem. The problem is related to "screen readers" feature.
When I open the menu, it adds a <span> above the dropdown (see the image below).

Also, that <span> has a class name css-bl6clz that doesn't exist (in a shadow-DOM component context) and this results in a strange behavior:

By the way, is there any way to deactivate this feature ("screen readers"), in order to not render this kind of dynamically html?
I've received a suggestion from emotions library group to use a custom container.
emotion-js/emotion#388Could not achieve this. Any help on this is greatly appreciated.
@pusulurm did you manage to solve this any other way?
@afvieira @pusulurm I have managed to solve this with a little workaround:
import React from 'react';
import createCache from '@emotion/cache';
import { NonceProvider } from 'react-select';
import AsyncCreatableSelect from 'react-select/async-creatable';
class MyNonceProvider extends NonceProvider {
createEmotionCache = (nonce) => {
return createCache({ nonce, container: this.props.container });
};
}
const MySelect = () => {
return (
<MyNonceProvider container={shadowRootNode}>
<AsyncCreatableSelect
...
/>
</MyNonceProvider>
);
};
It would be nice to add this container parameter to NonceProvider.createEmotionCache() in the next release.
same question here, I used it in Iframe, but when I click selector, it would add styles in parent window head.
I've received a suggestion from emotions library group to use a custom container.
emotion-js/emotion#388
Could not achieve this. Any help on this is greatly appreciated.@pusulurm did you manage to solve this any other way?
@afvieira , As I was in urgency , I ended up downgrading react select to 1.x version. This comes with a css file and I could bundle with my main css file.
Since my bundle css is scoped under shadow DOM it solved my problem. But I had to loose all latest features of react-select.
@norama
Thank you for sharing your solution. I'm glad you have some working solution.
I tried this approach and I have an issue and hope you can suggest on this.
With my own NonceProvider, I am able to get the style sections injected in my webcomponent and react select works fine with it. But I could see duplicate style sections added every time I render react select component. Where I have 10 select elements, the styles are duplicated 10 time.
Is there a way to avoid this flood of style tags from emotion ? Thanks again
@afvieira @pusulurm I have managed to solve this with a little workaround:
import React from 'react'; import createCache from '@emotion/cache'; import { NonceProvider } from 'react-select'; import AsyncCreatableSelect from 'react-select/async-creatable'; class MyNonceProvider extends NonceProvider { createEmotionCache = (nonce) => { return createCache({ nonce, container: this.props.container }); }; } const MySelect = () => { return ( <MyNonceProvider container={shadowRootNode}> <AsyncCreatableSelect ... /> </MyNonceProvider> ); };It would be nice to add this container parameter to
NonceProvider.createEmotionCache()in the next release.
didnt work ontouch on mobile
it looks like onInputBlur works instantly after touch to Control
but it works if touch on Indicator
@JedWatson plz help

```js
import React, { Component } from 'react';
import createCache from '@emotion/cache';
import Select, { NonceProvider } from 'react-select';
import memoizeOne from 'memoize-one';
class MyNonceProvider extends NonceProvider {
createEmotionCacheCustom = function (nonce) {
return createCache({ nonce, key: 'custom-select-style', container: this.props.container });
};
createEmotionCache = memoizeOne(this.createEmotionCacheCustom);
}
export default class CustomSelect extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
const shadowRootNode = document.getElementsByTagName('online-widget-osago')[0].shadowRoot.getElementById('osago-widget');
return (
/>
);
}
}```
@JedWatson
we add additional check and now it works
Can you update your package?
```js
_this.onTouchEnd = function (event) {
if (_this.userIsDragging) return; // close the menu if the user taps outside
// we're checking on event.target here instead of event.currentTarget, because we want to assert information
// on events on child elements, not the document (which we've attached this handler to).
if ((_this.controlRef && !_this.controlRef.contains(event.target) && _this.menuListRef && !_this.menuListRef.contains(event.target)) &&
(_this.controlRef && !_this.controlRef.contains(event.composedPath()[0]) && _this.menuListRef && !_this.menuListRef.contains(event.composedPath()[0]))) {
_this.blurInput();
} // reset move vars
_this.initialTouchX = 0;
_this.initialTouchY = 0;
};`
please update jet. thanks
I'm having an issue where React-Select seems to not be working at all inside the shadow DOM. Focusing the element, onChange, nothing seems to be working properly. Everyone else's issue is just that the styles aren't being applied?
So for anyone using React-Select inside a ShadowDOM, and having issues where events aren't firing:
I was able to add the following indented lines from the code snippet below to where I attach my React component to the page and have events work again. This is being done from within a Chrome Extension, other browsers may behave differently.
Object.defineProperty(reactRoot, 'ownerDocument', { value: shadowRoot });
shadowRoot.createElement = (...args) => document.createElement(...args);
shadowRoot.createElementNS = (...args) => document.createElementNS(...args);
shadowRoot.createTextNode = (...args) => document.createTextNode(...args);
where reactRoot is the element inside the ShadowDOM you are mounting your React component to using ReactDOM.render(...) and shadowRoot is the ShadowRoot.
https://github.com/facebook/react/issues/9242#issuecomment-543117675
@bonzoSPb
Hi, where did you add that additionnal check ? In which file ?
@bonzoSPb
Hi, where did you add that additionnal check ? In which file ?
In Select.js, check my fork
https://github.com/bonzoSPb/react-select/blob/master/src/Select.js
@bonzoSPb
Hi, where did you add that additionnal check ? In which file ?In Select.js, check my fork
https://github.com/bonzoSPb/react-select/blob/master/src/Select.js
Thank you @bonzoSPb ! 馃憤 It works great with a shadow DOM ! 馃挴
@JedWatson Can you please consider the solution of @bonzoSPb ?
I'm running react-select in an iframe and getting the same styling bug as @afvieira where the screen reader gets displayed. I've tried running the code that @bonzoSPb and @norama have posted but the styling is still off. I tried console logging the nonce and seeing that it's returning null, could that be an issue?
import React, { Component } from 'react';
import createCache from '@emotion/cache';
import Select, { NonceProvider } from 'react-select';
class MyNonceProvider extends NonceProvider {
createEmotionCache = (nonce) => {
console.log('nonce', nonce);
return createCache({ nonce, container: this.props.container });
};
}
export default class MySelect extends Component {
render() {
let iframeContainer = document.getElementById('custom-iframe-container');
return (
<MyNonceProvider container={iframeContainer}>
<Select
{...this.props}
/>
</MyNonceProvider>
);
}
};
@mikeyyyzhao Would you kindly mind creating a codesandbox demonstrating this issue? It would be much easier to get eyes on this and get this pushed up in priority.
@ebonow sure thing, here's the codesandbox. As you can see, react-select is showing the screen reader text and style is incorrect. Thanks in advance for your help!
I'll try to review this and get back to you soon. I'm still fairly new at this CSS-in-JS / Emotion thing, but I'll see what I can find out as I do know this is affecting others.
@JedWatson First of all thank you for great librarary!
Please consider on @bonzoSPb solution. There is two separate problems when yours library is used in Shadow DOM.
First problem can be easily fixed by adding custom NonceProvider and its not so annoying to fix it on users own.
The second is much worse. It cannot be fixed without modification of library code and its lead to dirty hacks when you need to use it.
Thanks for your interest in.
Most helpful comment
@JedWatson
we add additional check and now it works
Can you update your package?
```js
_this.onTouchEnd = function (event) {
if (_this.userIsDragging) return; // close the menu if the user taps outside
// we're checking on event.target here instead of event.currentTarget, because we want to assert information
// on events on child elements, not the document (which we've attached this handler to).