Has anyone had any success applying your own CSS style to GWT's NotificationMole.
If I add my own stylename then that style only applies to the outer DIV which is NOT removed when the mole is hidden, and I can't fing a way to apply style to the inner divs...
A dirty solution :
package com.google.gwt.user.client.ui; // important for package visibility access
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.SpanElement;
public class NotificationMoleHelper {
protected NotificationMole notificationMole;
public NotificationMoleHelper(NotificationMole notificationMole) {
super();
this.notificationMole = notificationMole;
}
public SpanElement getNotificationText() {
return notificationMole.notificationText;
}
public DivElement getHeightMeasure() {
return notificationMole.heightMeasure;
}
public DivElement getBorderElement() {
return notificationMole.borderElement;
}
/**
* Change heightMeasure's background color
*
* #param backgroundColor
*/
public void setBackgroundColor(String backgroundColor) {
getBorderElement().getStyle().setBackgroundColor(backgroundColor);
}
}
Example :
final NotificationMoleHelper notificationMoleHelper = new NotificationMoleHelper(notificationMole);
notificationMoleHelper.setBackgroundColor("#FF1111");
Well your NotificationMole has an associated ui.xml file, so any custom styles you want to apply should be applied there.
This might be easy: define your own style first, after init of the NotificationMole, just replace its built-in class with your defined ones, that's what i did in my project. Using DOM to replace classes or using gwtquery, both are OK.
A further alternative which might be more palatable for some people:
Set the id of the mole mole.getElement().setId("mole"); or mole.ensureDebugId("mole")
Then in your ui binder file add style:
width: 200px !important;
height: 60px !important;
}```
I tried without the !importants but gwt was including default widths and height so it wasn't listening to my styling. You won't need the !important if you add styles that gwt doesn't add by default.
Related
I created a server-side component with a shadow-root element.. Is it possible to import a style sheet for the elements within that shadow-root? The CssImport annotation does not work, and I couldn't find anything similar, that could work?!
I could create a static String and add an element, but a css-file-import would be better?! (and of course I could use the component without a shadow-root, but the question was "is it possible" ... )
MyCustomComponent.java
#Tag("my-custom-component")
#CssImport("./components/my-custom-component.css")
public class MyCustomComponent extends Component {
public MyCustomComponent() {
super();
ShadowRoot shadow = getElement().attachShadow();
Span span = new Span();
span.getElement().setAttribute("part", "caption");
Div div = new Div();
div.getElement().setAttribute("part", "content");
shadow.appendChild(span.getElement());
shadow.appendChild(div.getElement());
}
}
my-custom-component.css
:host [part='caption'] {
background-color: red;
}
:host [part='content'] {
background-color: blue;
}
I'm curious why you would want a shadow root around a Flow component, as it doesn't really provide any benefits other than CSS encapsulation.
The #CssImport annotation with the themeFor parameter won't help you in this case, as that only works with Web Components using ThemableMixin (https://github.com/vaadin/vaadin-themable-mixin/).
I'm not sure whether it's possible to load css into a shadow root with Flow, but as long as you have part attributes on all elements you want to style, you can do that with a regular (non-shadow-dom) stylesheet, like so:
my-custom-component::part(caption) {
color: red;
}
Just put that in your styles.css or wherever you have your app's normal global css.
In my CSS file, I have a class:
.test{
background: red;
}
But at the beginning of my app, I'd like to redefine this class based on the server response such that the background becomes blue or green depending on a variable.
It is very important to attribute to this class (.test) the new color as many of my elements have already this class and I don't want to apply a new class to them.
Not sure it's very clear but to summarize, I want to create a class from javascript (using angular 2) that will apply to the whole document.
The code below will find any style rules (including those inside media rules) that are part of the document, and overwrite any styles that are matched by the selector.
You can call modifyStyles('.test', { 'background': 'blue' }) on an instance of the service to make all styles with the .test class to have a blue background. You probably want to play with the way the selector functions, because in its current implementation any rule that has .test anywhere within it will have its background changed. You might prefer changing the regex to ^.test$ so that it matches .test and only .test.
#Injectable()
export class CssUpdateService {
constructor( #Inject(DOCUMENT) private document: Document) {
}
modifyStyles(selector: string, styles: any) {
const rulesToUpdate = this.findRules(new RegExp(`\b${selector}\b`, 'g'));
for (let rule of rulesToUpdate) {
for (let key in styles) {
rule.style[key] = styles[key];
}
}
}
/**
* Finds all style rules that match the regular expression
*/
private findRules(re: RegExp) {
let foundRules: CSSStyleRule[] = [];
let ruleListToCheck = Array.prototype.slice.call(this.document.styleSheets);
for (let sheet of ruleListToCheck) {
for (let rule of (<any[]>(sheet.cssRules || sheet.rules || []))) {
if (rule instanceof CSSStyleRule) {
if (re.test(rule.selectorText)) {
foundRules.push(rule);
}
}
else if (rule instanceof CSSMediaRule) {
ruleListToCheck.push(rule);
}
}
}
return foundRules;
}
}
EDIT (bc I was confused on your requirements initially) -
I don't think there's a good way to modify the global styles file after the application loads, but if I am wrong on that someone please correct me.
The shadow DOM makes this tricky. I would provide a runtime configuration variable to your module and then conditionally add a class to your application's root component.
<div class="outer-app-wrapper" [ngClass]="someValue">
Then in your global styles.css file, you can just define all the different variations of .test there could be.
.someValue1 .test {
background: red;
}
.someValue2 .test {
background: green;
}
.someValue3 .test {
background: yellow;
}
I think if you define all the variations in the styles.css file, you should be able to avoid having to use the 'host-context:' selector in the descendant components. There's no need to add any class to an element outside of Angular's scope like the 'body' element, just add it to the top-most element of your app, and as long as descendant components don't redefine the test class as it is defined in the global stylesheet, it should work fine.
Note - you could also use #HostBinding to add the classes to your root component if you don't want to add a wrapper element or modify an existing one
I have a Flex ActionScript component. How can I apply CSS to this component? I'm hoping to be able to apply styles from an external CSS file.
CSS Selector in file 'global.css':
.myPanel
{
color:#cccccc;
background-color:#333333;
border-color:#ff0000;
border-style:solid;
}
My Flex component:
package components
{
import mx.containers.Panel;
public class myPanel extends Panel
{
public function myPanel()
{
super();
}
override protected function createChildren():void
{
super.createChildren();
}
}
}
Unfortunately, if your component is defined via Actionscript, you'll have to manually define your css styles within the constructor or init function (e.g.):
//create and initialize css
var myCSS:StyleSheet = new StyleSheet();
myCSS.setStyle("body", {fontSize:'15',color:'#000066'});
myCSS.setStyle("h1", {fontSize:'25',color:'#000000'});
myCSS.setStyle("h2", {fontSize:'19',color:'#000000'});
myCSS.setStyle("a:link", {color:'#0000CC',textDecoration:'none'});
myCSS.setStyle("a:hover", {color:'#0000FF',textDecoration:'underline'});
myCSS.setStyle("b", {fontWeight:'bold'});
myCSS.setStyle("em", {fontWeight:'bold'});
An easier way would be to define your component as an mxml component and define the stylesheet in the header, like so:
<fx:Style source="../assets/css/global.css"/>
And your css file:
You can add style to your element:
this.setStyle('styleName', 'myPanel');
(not sure about this, need to be checked, but if you have element it will work) In this case selector
.myPanel
will work
To load css file use:
<fx:Style source="qx.css"/>
in you mxml file
I created a "Slider" subclass of QWidget and would like to be able to style it with Qt's stylesheets. Is there a way to declare the widget to Qt application so that this setting in the application stylesheet is applied to all sliders ?
Slider { background-color:blue; }
Or if this is not possible, can I use a class like this ?
QWidget.slider { background-color:blue; }
The widgets have a "className()" method that is accessible via the meta object. In my case this is:
slider.metaObject()->className();
// ==> mimas::Slider
Since the "Slider" class is in a namespace, you have to use the fully qualified name for styling (replacing '::' with '--'):
mimas--Slider { background-color:blue; }
Another solution is to define a class property and use it with a leading dot:
.slider { background-color:blue; }
C++ Slider class:
Q_PROPERTY(QString class READ cssClass)
...
QString cssClass() { return QString("slider"); }
While on the subject, to draw the slider with colors and styles defined in CSS, this is how you get them (link text):
// background-color:
palette.color(QPalette::Window)
// color:
palette.color(QPalette::WindowText)
// border-width:
// not possible (too bad...). To make it work, you would need to copy paste
// some headers defined in qstylesheetstyle.cpp for QRenderRule class inside,
// get the private headers for QStyleSheetStyle and change them so you can call
// renderRule and then you could use the rule to get the width borders. But your
// code won't link because the symbol for QStyleSheetStyle are local in QtGui.
// The official and supported solution is to use property:
// qproperty-border:
border_width_ // or whatever stores the Q_PROPERTY border
And finally, a note on QPalette values from CSS:
color = QPalette::WindowText
background = QPalette::Window
alternate-background-color = QPalette::AlternateBase
selection-background-color = QPalette::Highlighted
selection-color = QPalette::HighlightedText
I am using a TabBar and I want to style the component in different ways. So one time this style, another time that style. I thought this will work but it didn't:
TabBar t = new TabBar();
t.addTab( "1" );
t.addTab( "2" );
t.addStyleName( MyResources.INSTANCE.css().slickTab() );
And:
public interface MyResources extends ClientBundle
{
public static final MyResources INSTANCE = GWT.create(MyResources.class);
#Source("style.css") MyCssResource css();
}
public interface MyCssResource extends CssResource
{
String slickTab();
}
In the CSS
.slickTab .gwt-TabBar .gwt-TabBarItem {
background-color: #ff0000;
font-weight: normal;
}
But the appearance don't change. What I am doing wrong?
You might be able to force this in CSS.
.slickTab .gwt-TabBar .gwt-TabBarItem {
background-color: #ff0000 !important;
font-weight: normal !important;
}
Also, since you're adding a style which is subject to the parent style. If this is the case, you might need to set 'setStylePrimaryName' instead of adding it and toggle between style changes with handlers.
Change your CSS. .slickTab .gwt-TabBar .gwt-TabBarItem will match a TabBarItem inside a TabBar inside a slickTab. However, since the TabBar is the slickTab, and is not inside it, you need to do something like this (note .gwt-TabBar.slickTab):
.gwt-TabBar.slickTab .gwt-TabBarItem {
background-color: #ff0000;
font-weight: normal;
}
The interface MyCssResource need to be inside MyResources.
Here's an exemple :
public interface Resources extends ClientBundle
{
public static final Resources INSTANCE =
GWT.create( Resources.class );
/***********************************************
* Home
***********************************************/
#Source( "./css/home.css" )
public HomeCss getHomeCss();
public interface HomeCss extends CssResource
{
String loginBtn();
}
/***********************************************
* Another Page
***********************************************/
#Source( "./css/AnotherPage.css" )
public AnotherPage getAnotherPageCss();
public interface AnotherPage extends CssResource
{
String title();
}
}
This is the way I use all kind of Resource and it work really well.
Whenever you need to use it many time in the same method or function, you can do this :
HomeCss homeStyle = Resource.INSTANCE.getHomeCss();
yourPanel.setStyleName( homeStyle.yourPanel() );
Don't hesitate to ask if there's anything you didn't understand.
.slickTab .gwt-TabBar .gwt-TabBarItem is going to match something with class gwt-TabBarItem inside something with class gwt-TabBar inside something with class slickTab. I think you just want .slickTab .gwt-TabBarItem for the CSS selector.
I highly recommend using FireBug to inspect the HTML structure generated by GWT and how your CSS selectors are applied to it.
The line:
t.addStyleName( MyResources.INSTANCE.css().slickTab() );
Modifies the class element attribute. And INSTANCE.css().slickTab() does not do what you think. These methods without annotations bring back to java the #def's in the css. To make what you want add to MyCssResource:
#ClassName("slickTab")
String slickTab();
So, when GWT garbles the css upside down that method will return the corect class, ej "awEs". These GWT guys are obsessive about squeezing stuff :)
And remember, firebug & chrome-inspector are your friends.