You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PackagingSCSSOrCSSinAnAddon.asciidoc 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. ---
  2. title: Packaging SCSS Or CSS in An Addon
  3. order: 62
  4. layout: page
  5. ---
  6. [[packaging-scss-or-css-in-an-add-on]]
  7. = Packaging SCSS or CSS in an add-on
  8. The add-on architecture of Vaadin enables you to easily create reusable
  9. components and share them with the world. The add-on can be of various
  10. types: widgets, themes, server side components etc. Most of them contain
  11. Java code and classes, themes provide CSS and SCSS which can be used as
  12. the application theme but how should package add-ons which are not
  13. themes but still include CSS or SCSS? Let’s explore the options by
  14. creating a fancy `DangerButton` component (a native button which should
  15. have a red background).
  16. If we have an application (as opposed to an add-on) and want to create a
  17. red native button we have many options:
  18. *1. Use NativeButton with a style name and define the style in the
  19. application theme*
  20. [source,java]
  21. ....
  22. NativeButton dangerButton = new NativeButton("Don’t click me");
  23. dangerButton.addStyleName("danger");
  24. ....
  25. In the application theme:
  26. [source,css]
  27. ....
  28. .danger {
  29. background-color: red;
  30. }
  31. ....
  32. In our application we would of course encapsulate this in a
  33. `DangerButton` (`extends NativeButton`) which always adds the “danger”
  34. style name.
  35. *2. Use NativeButton with a style name and @Stylesheet to include the
  36. style*
  37. Do as above but create a custom css file which we place in the same
  38. folder as DangerButton.java and annotate DangerButton with
  39. @Stylesheet(“dangerbutton.css”). The @Stylesheet annotation will take
  40. care of publishing the css file and make the browser load it.
  41. *3. Create a custom connector and define the style inline*
  42. Create a custom component + connector by creating `DangerButton extends
  43. NativeButton` and `DangerButtonConnector
  44. extends NativeButtonConnector`. We can then manage to do this in the
  45. connector e.g. by setting an inline style when creating the widget. The
  46. upside of this is that it will work without a custom theme, the downside
  47. is that tuning the exact red color becomes cumbersome as you need to
  48. recompile the widget set (or use dev mode) for each update.
  49. *4. Include the style sheet in a widget set*
  50. Include the style sheet in a widget set by adding
  51. `<stylesheet src="dangerbutton-widgetset.css"/>` to the widget set
  52. gwt.xml file and adding the css file to the “public” folder inside the
  53. widget set folder (containing the gwt.xml file) so it will be included
  54. in the compiled widget set.
  55. *5. Dynamically inject the styles*
  56. Use NativeButton with a style name and dynamically inject the CSS
  57. needed, e.g.
  58. [source,java]
  59. ....
  60. NativeButton dangerButton = new NativeButton("Don’t click me");
  61. dangerButton.addStyleName("injectedDanger");
  62. getPage().getStyles().add(".injectedDanger {background-color: red;}");
  63. ....
  64. This approach does not require widget set compilation or a custom theme
  65. but does not support scss and injecting a lot of css this way can
  66. quickly add up to a lot of style tags in the page.
  67. [[what-about-the-add-on]]
  68. What about the add-on
  69. ^^^^^^^^^^^^^^^^^^^^^
  70. Returning to add-on discussion, which of the options above are viable
  71. for an add-on? What should we really use for our DangerButton add-on to
  72. keep it simple and avoid possible future problems?
  73. The first option which includes the application theme is not viable for
  74. an add-on as such except if we are fine with documenting that you should
  75. copy paste the css into your application theme.
  76. Option 2 seems like a good option but the day we add images or other
  77. resources to the style sheet we will run into problems as @Stylesheet
  78. only publishes the css file and nothing else. Including other style
  79. sheets (even when they are published with @Stylesheet also) does not
  80. work as we do not know the actual URL they will be available from at
  81. runtime and including images will also cause issues as we have no easy
  82. way of making them available. Also we cannot use SCSS with this
  83. approach.
  84. Option 3 and 4 with the custom widget set usually work out fine, you can
  85. even use SCSS for these (although it won’t be included in the
  86. application theme, e.g. prefixed correctly). However, if we want to keep
  87. things simple we do not want to make the add-on user compile widget set.
  88. We also do not want to go with option 5 as it does not support SCSS and
  89. have potential issues when overused, especially in older Internet
  90. Explorers.
  91. [[so-what-about-the-add-on..]]
  92. So, what about the add-on..?
  93. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  94. A sometimes overlooked feature of Vaadin is the VAADIN folder used to
  95. serve themes and widget sets to the browser. As a matter of fact all
  96. files inside the VAADIN folder are published directly as-is to the web,
  97. also when the VAADIN folder is in an add-on jar. So by placing our style
  98. sheet inside a “/VAADIN/addons/dangerbutton/” folder it will be
  99. available for the browser and any images or related style sheets will
  100. also be available (and relative paths will work). The only question
  101. remaining is how we can include the style sheet automatically for any
  102. user of our add-on and this can be done using `@StyleSheet` with the
  103. special `vaadin://` protocol, e.g.
  104. `@StyleSheet(“vaadin://addons/dangerbutton/styles.css”)`.
  105. [[that-does-not-work-with-scss]]
  106. That does not work with SCSS
  107. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  108. One of the nice features of SCSS is that the theme creator can define
  109. variables which you can use in your own scss file. If we are doing
  110. standalone compilation of the scss file to css we are not able to take
  111. advantage of these features. Also our styles will not be restricted to
  112. the application theme (using theme name prefixing) if it is not compiled
  113. at the same time as the application theme. Finally by including the
  114. styles in the application theme, all possible minifiers and similar can
  115. operate on the add-on styles also.
  116. To take full advantage of SCSS we can, instead of using the
  117. `@Stylesheet` annotation to include a css file directly, define in the
  118. add-on metadata that the addon jar contains a scss (or css) file which
  119. should be included when compiling the application theme. This is done
  120. with the `Vaadin-Stylesheets` attribute, for instance for our
  121. `DangerButton` as:
  122. ....
  123. Vaadin-Stylesheets: VAADIN/addons/dangerbutton/dangerbutton.scss
  124. ....
  125. A small gotcha here is that the `Vaadin-Stylesheet` attribute refers to
  126. the full path inside the add-on jar (i.e. starts with /VAADIN) whereas
  127. the /VAADIN part is included in the `vaadin://` protocol when using
  128. `@Stylesheet`.
  129. Now when you add the dangerbutton add-on jar to a project you will see
  130. that the addons.scss file gets automatically updated to include the
  131. dangerbutton css and it is compiled together with the rest of the
  132. application theme.