vaadin-framework/documentation/articles/PackagingSCSSOrCSSinAnAddon.asciidoc
2017-09-20 11:02:36 +03:00

166 lines
6.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Packaging SCSS Or CSS in An Addon
order: 62
layout: page
---
[[packaging-scss-or-css-in-an-add-on]]
Packaging SCSS or CSS in an add-on
----------------------------------
The add-on architecture of Vaadin enables you to easily create reusable
components and share them with the world. The add-on can be of various
types: widgets, themes, server side components etc. Most of them contain
Java code and classes, themes provide CSS and SCSS which can be used as
the application theme but how should package add-ons which are not
themes but still include CSS or SCSS? Lets explore the options by
creating a fancy `DangerButton` component (a native button which should
have a red background).
If we have an application (as opposed to an add-on) and want to create a
red native button we have many options:
*1. Use NativeButton with a style name and define the style in the
application theme*
[source,java]
....
NativeButton dangerButton = new NativeButton("Dont click me");
dangerButton.addStyleName("danger");
....
In the application theme:
[source,css]
....
.danger {
background-color: red;
}
....
In our application we would of course encapsulate this in a
`DangerButton` (`extends NativeButton`) which always adds the “danger”
style name.
*2. Use NativeButton with a style name and @Stylesheet to include the
style*
Do as above but create a custom css file which we place in the same
folder as DangerButton.java and annotate DangerButton with
@Stylesheet(“dangerbutton.css”). The @Stylesheet annotation will take
care of publishing the css file and make the browser load it.
*3. Create a custom connector and define the style inline*
Create a custom component + connector by creating `DangerButton extends
NativeButton` and `DangerButtonConnector
extends NativeButtonConnector`. We can then manage to do this in the
connector e.g. by setting an inline style when creating the widget. The
upside of this is that it will work without a custom theme, the downside
is that tuning the exact red color becomes cumbersome as you need to
recompile the widget set (or use dev mode) for each update.
*4. Include the style sheet in a widget set*
Include the style sheet in a widget set by adding
`<stylesheet src="dangerbutton-widgetset.css"/>` to the widget set
gwt.xml file and adding the css file to the “public” folder inside the
widget set folder (containing the gwt.xml file) so it will be included
in the compiled widget set.
*5. Dynamically inject the styles*
Use NativeButton with a style name and dynamically inject the CSS
needed, e.g.
[source,java]
....
NativeButton dangerButton = new NativeButton("Dont click me");
dangerButton.addStyleName("injectedDanger");
getPage().getStyles().add(".injectedDanger {background-color: red;}");
....
This approach does not require widget set compilation or a custom theme
but does not support scss and injecting a lot of css this way can
quickly add up to a lot of style tags in the page.
[[what-about-the-add-on]]
What about the add-on
^^^^^^^^^^^^^^^^^^^^^
Returning to add-on discussion, which of the options above are viable
for an add-on? What should we really use for our DangerButton add-on to
keep it simple and avoid possible future problems?
The first option which includes the application theme is not viable for
an add-on as such except if we are fine with documenting that you should
copy paste the css into your application theme.
Option 2 seems like a good option but the day we add images or other
resources to the style sheet we will run into problems as @Stylesheet
only publishes the css file and nothing else. Including other style
sheets (even when they are published with @Stylesheet also) does not
work as we do not know the actual URL they will be available from at
runtime and including images will also cause issues as we have no easy
way of making them available. Also we cannot use SCSS with this
approach.
Option 3 and 4 with the custom widget set usually work out fine, you can
even use SCSS for these (although it wont be included in the
application theme, e.g. prefixed correctly). However, if we want to keep
things simple we do not want to make the add-on user compile widget set.
We also do not want to go with option 5 as it does not support SCSS and
have potential issues when overused, especially in older Internet
Explorers.
[[so-what-about-the-add-on..]]
So, what about the add-on..?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A sometimes overlooked feature of Vaadin is the VAADIN folder used to
serve themes and widget sets to the browser. As a matter of fact all
files inside the VAADIN folder are published directly as-is to the web,
also when the VAADIN folder is in an add-on jar. So by placing our style
sheet inside a “/VAADIN/addons/dangerbutton/” folder it will be
available for the browser and any images or related style sheets will
also be available (and relative paths will work). The only question
remaining is how we can include the style sheet automatically for any
user of our add-on and this can be done using `@StyleSheet` with the
special `vaadin://` protocol, e.g.
`@StyleSheet(“vaadin://addons/dangerbutton/styles.css”)`.
[[that-does-not-work-with-scss]]
That does not work with SCSS
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
One of the nice features of SCSS is that the theme creator can define
variables which you can use in your own scss file. If we are doing
standalone compilation of the scss file to css we are not able to take
advantage of these features. Also our styles will not be restricted to
the application theme (using theme name prefixing) if it is not compiled
at the same time as the application theme. Finally by including the
styles in the application theme, all possible minifiers and similar can
operate on the add-on styles also.
To take full advantage of SCSS we can, instead of using the
`@Stylesheet` annotation to include a css file directly, define in the
add-on metadata that the addon jar contains a scss (or css) file which
should be included when compiling the application theme. This is done
with the `Vaadin-Stylesheets` attribute, for instance for our
`DangerButton` as:
....
Vaadin-Stylesheets: VAADIN/addons/dangerbutton/dangerbutton.scss
....
A small gotcha here is that the `Vaadin-Stylesheet` attribute refers to
the full path inside the add-on jar (i.e. starts with /VAADIN) whereas
the /VAADIN part is included in the `vaadin://` protocol when using
`@Stylesheet`.
Now when you add the dangerbutton add-on jar to a project you will see
that the addons.scss file gets automatically updated to include the
dangerbutton css and it is compiled together with the rest of the
application theme.