-
Notifications
You must be signed in to change notification settings - Fork 130
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
Move dynamically added styles into Shadow DOM #26
Comments
+1 |
Thanks for the suggestion! There's now a few graph types that folks have suggested that are part of extra packages, so I'll need to look into what the best strategy is for loading them; whether we should do so preemptively or only once the chart type is defined. |
+1 |
Thanks for the PR, @SmokyBob! I have a similar implementation in the works, but yours is cleaner, so I'll probably just use that, thanks! However, it's running into the same issue as mine: loading extra CSS. The table chart type, as well as a few others (such as the org chart type) use native HTML elements instead of SVG to draw the charts. This is all well and good, except that they load extra CSS to style them, and they do so by attaching it to the document head. That does not play well with the shadow DOM, and means the elements end up unstyled. I see several approaches to solve this problem:
The latter is my currently favoured approach, but I'm not particularly happy with any of these. I'd love to hear what the folks following the issue have to think on this! |
Hi @sgomes, glad to help. |
Tried to set up the observer to get the CSS. Here a gist with the code I've tried If anyone has any other Ideas, they are more than welcome |
So to add to this, as far as I can tell there's currently no way to implement support for the added styling. It's easy enough to detect changes, as @SmokyBob mentions, but we then need a way to actually apply them as needed:
Unless I'm missing something, the only solution for now seems to be to provide the markup, but no styling. Polymer 0.8 may give us a way of solving this, but for now it seems we're stuck :( |
I think the If users want to override the default styles they have a few options:
I'm happy to submit a PR with these changes as I want to get this working with the @sgomes what do you think? |
@philipwalton IMO adding the default styling, even if a bit old and didn't age well is a good idea and compromise. For different, more modern, Material styles we could have something like a |
@philipwalton Thanks for helping out! I think it's a reasonable compromise, yes. I'm not thrilled about us keeping static CSS against a library with regular updates, but I still think it's a better approach than just throwing markup at users with no context. @SmokyBob: I'd rather stay away from calling anything "Material" unless it's based on the spec or has gone through the right reviews, so I think we're better off just having the default styling. Again, it should be pretty easy for users to override styling, either outside of the component by using |
Finally got around to working on this. Here's the PR: #34 |
Finally found a way to import the style sheets added by the Google Chart API. Searching here and there found this article saying to use @import instead of the link tags... and works nicely. |
Any chance we'll get a resolution to this? I'm in need of the org chart and it has this same issue. |
Hi there, I reported original related issue #74 and investigated this a bit at the time. A simple approach to resolving seems to be observe type + data changes, assure polymer settings dom is shadow, google vis + service loader api state and internalize the external css for each instance. Sample code: // Lazily try to load table css for native shadow dom on type + data changes
observers: [
'_loadTableCss(type,data)'
],
// State of table css for shadow dom
_tableCssLoaded: false,
// The type or data was changed
// For shadowDom, we need to internalize css for type table
_loadTableCss: function (type) {
var loaded = this._tableCssLoaded;
var googReady = window.google != null && window.google.loader != null && window.google.visualization != null;
var isShadowDom = window.Polymer!=null && window.Polymer.Settings.dom === "shadow";
if (isShadowDom && !loaded && type == "table" && googReady) {
this._tableCssLoaded = true;
this.debounce("_loadTableCss", function(){
var url = window.google.loader.ServiceBase +
"/api/visualization/" +
window.google.visualization.Version +
"/" +
google.visualization.JSHash +
"/table+en.css";
var styleNode = document.createElement('style');
styleNode.innerHTML = "@import '" + url + "';";
this.shadowRoot.appendChild(styleNode);
});
}
} Some potential improvements would be to:
Thanks @jongeho1 |
So, I believe we can do the following:
Moving Callback:
This would mean that we have a duplicate of each sheet for each Something like: listeners: {
'loaded': '_checkForAndMoveStyles',
},
_checkForAndMoveStyles() {
const styleElementId = 'dynamic-chart-styles';
const chartStyleSelector = 'head > link[id^="load-css-"][href^="https://www.gstatic.com/charts/"]'
const chartStyles = document.querySelectorAll(chartStyleSelector);
if (!chartStyles) {
return;
}
const imports = styleSheets.map((css) => {
return css.getAttribute('href');
}).join("';\n @import '");
// In the case of multiple loads, an element already exists.
let styleElement = this.shadowRoot.querySelector('#${styleElementId}');
const existing = !!styleElement;
if (!existing) {
styleElement = document.createElement('style');
styleElement.setAttribute('id', styleElementId)
}
styleElement.innerHTML = `@import '${imports}';`;
if (!existing) {
this.shadowRoot.appendChild(styleElement);
}
}, |
Here is a demo of it in action and a preview of the changes I had in mind. |
fixed in #223 |
It would be good if google-chart support the Table graph.
The text was updated successfully, but these errors were encountered: