Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / guides / theming / README.md
1 # Theming
2
3 Ext JS 4 has a brand new theming system to customize the look of your application while still supporting all browsers.
4
5 ## A Brief Introduction to SASS & Compass
6
7 SASS is a pre-processor which adds new syntax to CSS allowing for things like variables, mixins, nesting, and math/color functions. For example, in SASS we can write:
8
9     $blue: #3bbfce;
10     $margin: 16px;
11
12     .content-navigation {
13         border-color: $blue;
14         color: darken($blue, 9%);
15     }
16
17     .border {
18         padding: $margin / 2;
19         margin: $margin / 2;
20         border-color: $blue;
21     }
22
23 And it will compile to:
24
25     .content-navigation {
26         border-color: #3bbfce;
27         color: #2b9eab;
28     }
29
30     .border {
31         padding: 8px;
32         margin: 8px;
33         border-color: #3bbfce;
34     }
35
36 To see the wide variety of other features available in SASS, please see [http://sass-lang.com/](http://sass-lang.com/). Compass extends SASS by adding a variety of CSS3 mixins and providing the extension system that Ext JS leverages. With Compass, one can include rules like:
37
38     $boxheight: 10em;
39
40     .mybox {
41         @include border-radius($boxheight/4);
42     }
43
44 Which compiles into:
45
46     .mybox {
47         -webkit-border-radius: 2.5em;
48         -moz-border-radius: 2.5em;
49         -o-border-radius: 2.5em;
50         -ms-border-radius: 2.5em;
51         -khtml-border-radius: 2.5em;
52         border-radius: 2.5em;
53     }
54
55 You can learn more about the pre-included mixins with Compass and the other tools it provides here: [http://compass-style.org/docs/](http://compass-style.org/docs/).
56
57 ## Requirements
58
59 ### Ruby
60
61 #### Mac OSX
62
63 XCode installs Ruby and all necessary dependencies to your Mac when installed.
64
65 Xcode can be found on the Apple Developer Website: [http://developer.apple.com/xcode/](http://developer.apple.com/xcode/)
66
67 #### Windows
68
69 Visit [http://rubyinstaller.org/](http://rubyinstaller.org/) and download the latest packaged version of Ruby (1.9.2 at the time of writing)
70
71 ### Compass/SASS gem
72
73 #### Mac OSX
74
75 In `/Applications/Utilities/Terminal.app`, run the following code (you will be asked for your password):
76
77     sudo gem install compass
78
79 You can verify you have Compass and Sass installed by running the following in `Terminal.app`:
80
81     compass -v
82
83     sass -v
84
85 At the time of writing, the latest version of Compass is `0.11.1 (Antares)`. The latest version of Sass is `3.1.1 (Brainy Betty)`
86
87 #### Windows
88
89 Select **Start Command Prompt with Ruby** from the new Start Menu option.
90
91 Type the following:
92
93     gem install compass
94
95 You can verify you have Compass and Sass installed by running the following in **Terminal.app**:
96
97     compass -v
98     sass -v
99
100 At the time of writing, the latest version of Compass is `0.11.1 (Antares)`. The latest version of Sass is `3.1.1 (Brainy Betty)`
101
102 ## Directory Structure
103
104 The Ext JS SDK comes with a template which can be used as a base for your new theme. If you followed the [Getting Started](#/guide/getting_started) guide, you should have a directory for your application with a subfolder `extjs` containing the Ext JS SDK. It should look something like this:
105
106     appname/
107     appname/extjs/
108     appname/app.js
109     appname/index.html
110
111 Copy the template resources folder from `appname/extjs/resources/themes/templates/resource` to your root application folder:
112
113     appname/
114     appname/resources/
115     appname/resources/css/
116     appname/resources/sass/
117     appname/resources/sass/config.rb
118     appname/resources/sass/my-ext-theme.sass
119
120 You will also need to copy the images from `appname/extjs/resources/themes/images/default` to `appname/resources/images`.
121
122 Ensure the path to your Ext JS folder is correct in `appname/resources/sass/config.rb`:
123
124     # $ext_path: This should be the path of the Ext JS SDK relative to this file
125     $ext_path = "../../extjs"
126
127 Due to a bug in Ext JS 4.0.2a you will also need to edit line 62 of `appname/extjs/resources/themes/lib/utils.rb` from this:
128
129     images_path = File.join($ext_path, 'resources', 'themes', 'images', theme)
130
131 to this:
132
133     images_path = relative_path
134
135 This ensures images will be served from `appname/resources/images` rather than `appname/extjs/resources/images`
136
137 ## Compiling your CSS
138
139 Compiling your CSS is a simple process using Compass.
140
141 First, change to your sass directory in `appname/resources/sass`, then run the following command in **Terminal.app on Mac OSX** or **Command Prompt on Windows**:
142
143     > compass compile
144
145 This should output the following:
146
147     > create ../css/my-ext-theme.css
148
149 Your minified css file should now be in `appname/resources/css/my-ext-theme.css`.
150
151 ## Changing global SASS variables
152
153 The Ext JS theming system comes with global SASS variables which you can use to change the look of your application with a few lines of code.
154
155 These SASS variables can be added to your `appname/resources/sass/my-ext-theme.scss` file, but they **must** be inserted before the call to `@import 'ext4/default/all'`. You can see an example commented out at the top of your `my-ext-theme.scss` file:
156
157     // Insert your custom variables here.
158     // $base-color: #aa0000;
159
160 Try uncommenting this line and changing the base-color to something else, perhaps the green #a1c148.
161
162 Now regenerate your theme by navigating to `appname/resources/sass` and running `compass compile`
163
164 ### Available Variables
165
166 Navigate to `appname/extjs/resources/themes/stylesheets/ext4/default/variables` directory. This directory contains all defined variables for each component in Ext JS 4.
167
168 The naming convention for variables follows CSS property names, prepends by the component name. For example:
169
170 - **Panel border radius**
171   - CSS Property: `border-radius`
172   - Variable: ``$panel-border-radius``
173
174 - **Panel body background color**
175   - CSS Property: `background-color`
176   - Variable: `$panel-body-background-color`
177
178 - **Toolbar background color**
179   - CSS Property: `background-color`
180   - Variable: `$toolbar-background-color`
181
182 You can copy any of these variables and add them to your `appname/resources/sass/my-ext-theme.scss` file **before** the `@import 'ext4/default/all'` line.
183
184 ## View the Results
185
186 To view your new theme, lets overwrite `app.js` with the Theme example from the main SDK. This example shows most Ext JS components on a single page. Copy `appname/extjs/examples/themes/themes.js` to `appname/app.js`.
187
188 Update `appname/index.html` to the following:
189
190     <html>
191     <head>
192         <title>Ext Theme</title>
193
194         <link rel="stylesheet" type="text/css" href="resources/css/my-ext-theme.css">
195         <script type="text/javascript" src="extjs/ext-debug.js"></script>
196         <script type="text/javascript" src="app.js"></script>
197     </head>
198     <body></body>
199     </html>
200
201 Now open `index.html` in your browser and you should see your new theme in action. Try updating the base color in `my-ext-theme.sass` to something else, recompile your sass, and refresh your browser to see the change. Also try experimenting with other sass variables.
202
203 ## Component UIs
204
205 Every component in the Ext JS framework has a `ui` configuration (which defaults to `default`). This property can be changed to allow components in your application to have different styles.
206
207 The `ui` of any component can be changed at any time, even after render, by using the `setUI` method. An example of this can be found in `examples/panel/bubble-panel.html`.
208
209 ### Creating new Ext JS UIs
210
211 Some Ext JS components have SASS `@mixin`'s which allow you to quickly generate new UIs. These include: `Ext.panel.Panel`, `Ext.button.Button`, `Ext.Toolbar` and `Ext.window.Window`.
212
213 Creating these new UIs is simple. Simply call the associated `@mixin` (found in the documentation) for the component you want to create a new UI for.
214
215 Lets look at the Panel `@mixin` as an example (which can be found in `examples/panel/bubble-panel/sass/bubble-panel.scss`):
216
217     @include extjs-panel-ui(
218         'bubble',
219
220         $ui-header-font-size: 12px,
221         $ui-header-font-weight: bold,
222         $ui-header-color: #0D2A59,
223         $ui-header-background-color: #fff,
224         $ui-header-background-gradient: null,
225
226         $ui-border-color: #fff,
227         $ui-border-radius: 4px,
228         $ui-body-background-color: #fff,
229         $ui-body-font-size: 14px
230     );
231
232 The above code will create a new `ui` for any Ext.panel.Panel component, which you can then use in your application by specifying the `ui` configuration:
233
234     Ext.create('widget.panel', {
235         ui: 'bubble',
236         width: 300,
237         height: 300,
238         title: 'Panel with a bubble UI!'
239     });
240
241 ## Supporting Legacy Browsers
242
243 In most cases when creating new UI's, you will want to include background gradients or rounded corners. Unfortunately legacy browsers do not support the corresponding CSS3 properties, so we must use images instead.
244
245 With Ext JS 4, we have included a Slicing tool which does the hard work for you. Simply pass it a manifest file of your new UI's (if you have created any) and run the tool from the command line.
246
247 ### How it works
248
249 The slicing tool creates a new browser instance, which loads Ext JS and a specified CSS file. Once loaded, it parses a JavaScript file which includes every Ext JS component that needs styling (panel, window, toolbar, etc.). It then analyzes each of those components and determines the size and location of each image that needs to be sliced. It then slices each of the images, sprites them together and saves them in the location defined in the manifest.
250
251 The slicer too itself can be run from the command line and is installed as part of the SDK Tools package. It can be run by calling `sencha slice theme`. Example usage (assuming you are in your application root directory):
252
253     sencha slice theme -d extjs -c resources/css/my-ext-theme.css -o resources/images -v
254
255 It accepts several arguments:
256
257 - **--css[=]value, -c[=]value**
258   > The path to your theme's complete CSS file, e.g., ext-all-access.css. Uses
259   > the default Ext JS 4 theme CSS if not provided.
260
261 - **--ext-dir[=]value, -d[=]value (required)**
262   > The path to the root of your Ext JS 4 SDK directory.
263
264 - **--manifest[=]value, -m[=]value**
265   > The path to your Theme Generator JSON manifest file, e.g., manifest.json.
266   > Uses the default packaged manifest if not provided.
267
268 - **--output-dir[=]value, -o[=]value**
269   > The destination path to save all generated theme images. This should be inside the `resources/themes/images/<themename>/` directory.
270   > Defaults to the current working directory.
271
272 - **--verbose, -v**
273   > Display a message for every image that is generated.
274
275 ### Usage
276
277 1.  **Compile your CSS**
278
279     You must ensure your SASS theme file has been compiled as this is used for the slicer. Passing no CSS file would result in the slicer to revert to the default ext-all.css file, which would be pointless in most cases.
280
281 2.  **Creating your manifest file (optional)**
282
283     The manifest file is a simple JavaScript file which tells the Slicing tool which custom UI's you would like to slice. This step is only necessary when you have created new UI's.
284
285     Let's look at the bubble panel example again:
286
287         Ext.onReady(function() {
288             Ext.manifest = {
289                 widgets: [
290                     {
291                         xtype: 'widget.header',
292                         ui   : 'bubble'
293                     },
294                     {
295                         xtype: 'widget.panel',
296                         ui   : 'bubble'
297                     }
298                 ]
299             };
300         });
301
302     As you can see, you define an Object called `Ext.manifest` and give it an Array property called `widgets`. In this Array you should insert an object containing the `xtype` and `ui` of the component you want to generate the images for.
303
304     **It is important that the `Ext.manifest` Object is defined inside the `Ext.onReady` method.**
305
306 3. **Generating your images**
307
308     Now all that is left is to run the command, including the arguments to the Ext JS SDK folder, your theme CSS file and the output directory of the sliced images.
309
310         sencha slice theme -d extjs -c resources/css/my-ext-theme.css -o resources/images -v
311
312 ## FAQ
313
314  * **I am getting a '`error resources/sass/my-ext-theme.scss (Line 8: File to import not found or unreadable: ext4/default/all)`' error when I compile?**
315
316     > This is because Compass cannot file the Ext JS 4 theme files. Ensure the `$ext_path` in the `sass/config.rb` file is correct.