1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<div class="intro">
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>`Widget` is the foundation class from which all YUI 3 widgets are derived. It provides the following pieces of core functionality on top of what <a href="../base/index.html">Base</a> already provides:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li>Adds the `render` lifecycle moment, to <a href="../base/index.html">Base's</a> `init` and `destroy` moments</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li>Abstract rendering methods to promote a consistent MVC pattern across widgets</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li>A common set of widget attributes</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li>Consistent markup generation support</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li>Consistent class-name generation support</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li>Built-in progressive enhancement support</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h2 id="responsibilities">What Widget Provides</h2>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h3 id="structure">Class Structure And Responsibilities</h3>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<img src="{{componentAssets}}/widget-class-diagram.png" alt="The widget class diagram" width="436" height="357">
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo<p>`Widget` provides the foundation class on which all YUI 3 widgets will be built.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen DesaiAlthough instantiable and usable by itself, it is designed to be extended to create widgets which address
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desaispecific user interaction patterns.</p>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo<p>The `Widget` class extends <a href="{{apiDocs}}/Base.html">`Base`</a>. Therefore it provides
f8bf159b72cbed0438d9d1d674e45fbf2d5581a9Ryuichi Okumurathe same `Attribute`, `Event.Provider` and `Plugin.Host` support as <a href="../base/index.html#extendbase">`Base`</a> does.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>It adds the following core functionality:</p>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <dt><strong>Basic Attributes</strong></dt>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <dd>It introduces a common set of attributes that will be available on any widget.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai For example, `boundingBox`, `contentBox`, `width`, `height`, `visible`, `focused` and `disabled`.</dd>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt><strong>Render Lifecycle Phase</strong></dt>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <dd>It adds the `render` lifecycle method (and event) to the `init` and `destroy`
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai lifecycle methods provided by `Base`.</dd>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <dt><strong>Abstract Rendering Methods</strong></dt>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <dd>It establishes abstract methods `renderUI`, `bindUI` and `syncUI` to
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai provide consistent entry points for rendering across all widgets.</dd>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt><strong>Consistent Progressive Enhancement</strong></dt>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dd>It provides a common entry point for <a href="http://en.wikipedia.org/wiki/Progressive_Enhancement">Progressive Enhancement</a> during widget initialization and also provides
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai the infrastructure to hide progressively enhanced markup to avoid flashes of unstyled content.</dd>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt><strong>String Localization</strong></dt>
31c505368ffbf78b2d9a8b7dba5d792023f3d7e2Satyen Desai The `strings` attribute provides a consistent API for string management in all Widgets.
31c505368ffbf78b2d9a8b7dba5d792023f3d7e2Satyen Desai Widget developers can define strings for their widget in an external language bundle when packaging their
31c505368ffbf78b2d9a8b7dba5d792023f3d7e2Satyen Desai widgets as a YUI module, and use the Internationalization utility to pull in strings for a given locale
31c505368ffbf78b2d9a8b7dba5d792023f3d7e2Satyen Desai as demonstrated in the <a href="../intl/intl-basic.html">Language Resource Bundles</a> example.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h3 id="attributes">Basic Attributes</h3>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>Widget establishes a common set of attributes which will be available in all YUI 3 widgets. The core attributes are discussed below:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <tr><th>Attribute</th><th>Description</th></tr>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <tr><td>`boundingBox`</td><td>The widget's outermost node, used for sizing and positioning; this element can also serve as a containing node for any decorator elements used for skinning.</td></tr>
0b3ce38e1bfc8f6ea7e23b3610172f92295ea64eEric Ferraiuolo <tr><td>`contentBox`</td><td>A node that is a direct descendant of a widget's bounding box and houses its content. This will generally be the node that establishes the look and feel for the widget.</td></tr>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <tr><td>`srcNode`</td><td>An existing node in the document provided by application developers when progressively enhancing existing markup to create the widget. By default, this resolves to the `contentBox`.</td></tr>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <tr><td>`tabIndex`</td><td>The tabIndex, applied to the bounding box.</td></tr>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <tr><td>`focused`</td><td>Flag, indicating if the widget currently has focus. `Widget` marks the bounding box with a "focused" class, but other than that the focus implementation is left to the specific widget class.</td></tr>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <tr><td>`disabled`</td><td>Flag, indicating if the widget is disabled. `Widget` marks the bounding box with a "disabled" class, but other than that the disabled implementation is left to the specific widget class.</td></tr>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <tr><td>`visible`</td><td>Flag, indicating whether or not the widget is visible. `Widget` marks the bounding box with a "hidden" class. The hidden implementation is left to the CSS delivered by the specific widget class (viz. whether or not the widget uses visibility, display or off screen positioning to actually hide the widget).</td></tr>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <tr><td>`height`</td><td>String with units, or a number, representing the height of the widget. If a number is provided, the default unit, defined by `Widget`'s `DEF_UNIT`, property is used. The height is applied to the bounding box.</td></tr>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <tr><td>`width`</td><td>String with units, or a number, representing the width of the widget. If a number is provided, the default unit, defined by `Widget`'s `DEF_UNIT`, property is used. The width is applied to the bounding box.</td></tr>
31c505368ffbf78b2d9a8b7dba5d792023f3d7e2Satyen Desai <tr><td>`strings`</td><td>The collection of strings used to label elements of the widget's UI. These should ideally be packaged separately from the Widget code, as discussed in the <a href="../intl/intl-basic.html">Language Resource Bundles</a> example.</td></tr>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h3 id="rendering">Rendering Methods</h3>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo<p>`Widget` adds the `render` method/lifecycle phase to the
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai`init` and `destroy` phases established by Base.</p>
be02c547ba97d37db2484be30f7f1510cf92a914Eric FerraiuoloThe `render` method establishes the point at which the widget lays down its UI by adding elements to (or modifying existing elements in) the DOM and
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolosetting up listeners to activate that UI. Having a distinct rendering phase promotes widget classes that separate state and corresponding logic
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desaifrom the way the widget UI is displayed. This separation tends to allow the widget's state to be safely modified and queried before it is displayed or rendered to the DOM.
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo<p>Additionally, this separation of concerns leads to code being split into methods that manipulate the widget's state or handle core "app" logic versus methods which work with the DOM.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen DesaiFollowing this practice makes it easier to customize and test one area or the other.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h4>The Lifecycle Methods: `init, destroy, render`</h4>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo<p>As with `init` and `destroy`, the `render` method on `Widget` is final and delegates to the
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desaiwidget implementation's `renderer` method to perform the actual rendering work:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt><a href="{{apiDocs}}/Base.html#method_init">`init`</a> <em>(inherited from `Base`)</em>:</dt>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai The `init` method loops through the class hierarchy, top down (Base first, subclass last) and:
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li>Configures attributes for each class, based on the class' `ATTRS` static property.</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li>Then, invokes the `initializer` method for the class.</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>The `init` method fires an `init` event, which can be prevented to stop initialization from proceeding.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt><a href="{{apiDocs}}/Base.html#method_destroy">`destroy`</a> <em>(inherited from `Base`)</em>:</dt>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>Invokes the `destructor` method for all classes in the widget hierarchy, bottom up (subclass first, Base last).</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>The `destroy` method fires a `destroy` event, which can be prevented to stop destruction from proceeding.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt><a href="{{apiDocs}}/Widget.html#method_render">`render`</a>:</dt>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <p>Invokes the `renderer` method for the Widget instance. Unlike the `initializer` and `destructor`, this method
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai is not chained automatically for the widget's class hierarchy.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai The `render` method accepts a `parentNode` argument, which can be used to specify an existing node in the document, where the widget should be appended, when rendered.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai If the widget's contentBox or boundingBox don't already exist in the document, and the `parentNode` argument is not provided, the widget is inserted as the first child of the document's body element (we <em>insert</em> as the default behavior, to avoid IE6 "Operation Aborted" errors).
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>The `render` method fires a `render` event, which can be prevented to stop rendering from proceeding.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h4>Widget's `renderer` Method</h4>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>Widget provides a <a href="{{apiDocs}}/Widget.html#method_renderer">`renderer`</a> method implementation, which for most simple widgets will not need to be over-ridden.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen DesaiThis `renderer` method is shown below:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desairenderer: function() {
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen DesaiThe `renderUI`, `bindUI` and `syncUI` are abstract (empty) methods in the `Widget` class which attempt to establish a common pattern for widget development.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen DesaiThe intended role of each of these methods is described below, and most widgets will simply implement these methods based on their expected roles:
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt><a href="{{apiDocs}}/Widget.html#method_renderUI">`renderUI`</a></dt>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dd>This method is responsible for creating and adding the nodes which the widget needs into the document (or modifying existing nodes, in the case of progressive enhancement).
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai It is usually the point at which the DOM is first modified by the widget.</dd>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt><a href="{{apiDocs}}/Widget.html#method_bindUI">`bindUI`</a></dt>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <dd>This method is responsible for attaching event listeners which bind the UI to the widget state.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai These listeners are generally attribute change listeners — used to update the state of the UI in response to changes in the attribute's value.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai It also attaches DOM event listeners to the UI to map user interactions to the widget's API.</dd>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt><a href="{{apiDocs}}/Widget.html#method_syncUI">`syncUI`</a></dt>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dd>This method is responsible for setting the initial state of the UI based on the current state of the widget at the time of rendering.</dd>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h3 id="progressive">Progressive Enhancement</h3>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>The `Widget` class establishes a standard entry point for widgets that need to provide support for <a href="http://en.wikipedia.org/wiki/Progressive_Enhancement">Progressive Enhancement</a>; this entry point is provided in the form of an `HTML_PARSER` property on each class.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p><a href="{{apiDocs}}/Widget.html#property_Widget.HTML_PARSER">`HTML_PARSER`</a> is a static property, used to define a hash of selectors or functions that are responsible for (a) parsing content for the widget from existing DOM elements and (b) extracting attribute configuration values for use during initialization.</p>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo // Set attributes which are Node references
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai // using selector syntax (uses node.one())
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo // Set attributes which are multiple Node references
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo // using selector syntax (uses node.all())
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai itemNodes: ["li.yui3-listitem"],
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo // Set attributes using a parse function. Execution context
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai // is set to the widget instance
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo label: function(srcNode) {
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai return srcNode.one("input.yui3-title").get("innerHTML");
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai xValue: function(srcNode) {
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai return srcNode.one("input.yui3-slider-xvalue").get("value");
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai yValue: function(srcNode) {
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai return srcNode.one("input.yui3-slider-yvalue").get("value");
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>The `HTML_PARSER` property is evaluated when the Widget class' `initializer` method is invoked (so Widget sub-classes receive the configuration
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuoloobject passed into the constructor). The object is iterated, to create a filled out configuration object for the widget, based on the content the user points to using the `srcNode` attribute.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen DesaiFor example, the parser definition above may lead to the following object literal when evaluated:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai titleNode: NodeRef,
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai itemNodes: NodeListRef (multiple nodes),
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai label: "My Widget",
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai xValue: "10",
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai yValue: "20"
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>This object is merged with the user configuration object passed into the constructor (markup can be thought of as alternate source/format for configuration data), with the configuration object passed to the widget constructor taking precedence if a value for an attribute is found in both places.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h4 id="hidingmarkup">Hiding Progressively Enhanced Markup</h4>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>In addition to providing a common entry point for progressively enhanced solutions through the `HTML_PARSER`, Widget also provides the CSS hooks you need to initially hide content which will be progressively enhanced.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li> If JavaScript <em>is not</em> enabled the content provided by the markup for the widget, should be visible and accessible.</li>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <li> If JavaScript <em>is enabled</em>, the widget source markup should be hidden as early as possible, to avoid the user seeing the flash of
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai unstyled content while the widget's JavaScript and CSS components are delivered to the page and the widget is rendered.</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li> Once the widget is fully rendered it should then be displayed.</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>In order to make this happen:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li> <p>The <a href="../yui/index.html">YUI</a> seed file will stamp the documentElement (the <HTML> element) with a class of `'yui3-js-enabled'`.</p></li>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <li> <p>Application developers can then add a class name representing the "loading" state, to the widget's content (e.g. `'yui3-widget-loading'`).</p><p>This class can be used in combination with the "yui3-js-enabled" class name to
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai create style rules to hide the widget content while its JavaScript is being loaded.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai .yui3-js-enabled .yui3-widget-loading {
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai display: none;
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai .yui3-js-enabled .yui3-overlay-loading {
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai /* Hide overlay markup offscreen */
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai position:absolute;
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai top:-1000em;
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai left:-1000em;
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>As shown in the example above, there is support for use of both a generic widget and type-specific widget class name by default ("yui3-widget-loading" and "yui3-tabview-loading").</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li> <p>Widget's renderer will remove the "loading" class names from both the bounding box and content box once the widget is rendered, allowing the fully functional widget to be revealed.</p></li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h3 id="markup">Rendered Markup</h3>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo<p>The `Widget` class establishes a common markup format for all widgets, through its <a href="{{apiDocs}}/Widget.html#attr_boundingBox">`boundingBox`</a> and
f7da8d036724b1c753c75badbf8758f6ef48c0a0Derek Gathright<a href="{{apiDocs}}/Widget.html#attr_contentBox">`contentBox`</a> attributes.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai Most widgets will have a bounding box wrapping a content box. They are both `DIV`s by default but can be customized by overriding the `BOUNDING_TEMPLATE` and `CONTENT_TEMPLATE` prototype properties.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai However, the widget developer can also specify the `CONTENT_TEMPLATE` to be null, if their widget implementation does not require a two-box structure. In this case, both the boundingBox and contentBox attributes will point to the same node.
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo The widget will create either of the nodes if they are not provided in the constructor, and add them to the document when the widget's `render` method is called.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai As mentioned previously, if the `render` method is passed a node reference, the widget's bounding box is appended to that node.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h4>The Bounding Box</h4>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>The bounding box is the outermost element owned by the widget and is used for functional, rather than visual, purposes.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<ul class="topiclist">
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><p class="topic">A class name identifying the widget is added to the bounding box.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>The default format for the class name is "yui3-[widgetname]". For example, for Slider, the "yui3-slider" class name is added to the bounding box.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><p class="topic">Additionally, class names for all widget classes in the class hierarchy are also used to tag the bounding box.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>For example, for a MultiThumbSlider, which may extend Slider, the bounding box is marked with the classes "yui3-widget", "yui3-slider" and "yui3-multithumbslider" (this is the only place where we mark an element with class names for all widget classes in the hierarchy).</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p class="topic">Class names used for state management by the widget instance are also applied to the bounding box.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>The general format is "yui3-[widgetname]-[state]". For example "yui3-slider-hidden", "yui3-slider-disabled".</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p class="topic">The widget's width and height values are applied to the bounding box if set, as are top/left (xy) positioning values, for positioned widgets.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p class="topic">The bounding box is not expected to have any visual properties (e.g. borders, padding, etc.) applied to it.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>However it will have CSS defining how the widget impacts the document flow. For example, the bounding box type ("display:inline", "display:inline-block", "display:block") and the positioning scheme ("position:absolute", "position:relative").</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h4>The Content Box</h4>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>The content box is a child of the bounding box. The widget will add the elements which make up its core UI inside the content box.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<ul class="topiclist">
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p class="topic">The content box also has an identifying class name applied to it.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>The default format is "yui3-[widgetname]-content". For example "yui3-slider-content".</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><p class="topic">Visual treatment for the widget is applied to the content box (e.g. borders, padding, background-color, etc.).</p></li>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <p class="topic">For progressively enhanced solutions, generally the application developer will only provide what will be the content box on the page and pass it into the constructor as the `srcNode` (rather than the bounding box).</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>The bounding box will be added dynamically when the widget is instantiated. This maintains semantic value (the content box ends up containing existing content), and avoids unnecessary markup on the page up front.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h4>Widget Markup Diagram</h4>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>The following illustration demonstrates how the markup and class names for a widget's bounding box and content box come together.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<img src="{{componentAssets}}/widget-dom.png" height="357" width="524" alt="Illustration of the two-box DOM layout for a widget.">
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h4>Why Two Nested Boxes?</h4>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>Providing nested boxes for all widgets provides benefits for CSS application, decorative element support and bounding box dimension handling. These are detailed below:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li>The nested structure allows the bounding box to act as a container for any additional decorator elements which need to be added for the widget, for example, elements which support rounded-corners, shadows, or shimming. These can live as siblings of the content box, and can be positioned and sized more efficiently since they have a common parent container.</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li>Additionally, due to the consistent structure across all widgets, generic plugins can be written to provide the above decorator support, which are re-usable across all widgets.</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li>Having a box without border and padding applied (the bounding box) allows for consistent width and height application across browser box model differences.</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h3 id="CSS">Class Names and CSS</h3>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>In order to provide consistent class names for use across all widgets, the `Widget` class provides two methods which are simple wrappers for the `ClassNameManager` utility, and leverage the `NAME` property defined for widget classes.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt>Instance Method: `getClassName(arg1, arg2, arg3 ...)`</dt>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>This method can be used to create class names which begin with the configured prefix for the application ("yui3-" by default) and the name of the widget (the `NAME` property, lowercase). For example:</p>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo // A method on a Spinner widget instance,
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai // with Spinner.NAME = "spinner";
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai renderSpinnerButton: function() {
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai // generates the class name "yui3-spinner-increment-major"
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai var btnClassName = this.getClassName("increment", "major");
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p><strong>Note:</strong> The `ClassNameManager.getClassName(arg1, arg2, arg3 ...)` method can be used as a replacement for the above method, when class names need to be generated in a static context, by passing in the widget implementation's `NAME` property as the first argument. For example:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai // Generates the class name "yui3-spinner-button"
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai Spinner.BUTTON_TEMPLATE = Y.ClassNameManager.getClassName(
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt>Static Method: `Widget.getClassName(arg1, arg2, arg3 ....)`</dt>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai This static version of the method (invoked directly on the `Widget` class, as opposed to "`this`") can be used to create class names which begin with a "yui3-widget" prefix. This maybe useful for plugins, which need to ship with CSS which targets a fixed class name, regardless of the widget instance to which they are applied.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai For example:
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai // generates the class name "yui3-widget-shim"
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>If, as a custom widget developer, you want to override the default prefix (`yui3-[widgetname]`), you can define a static `CSS_PREFIX` property on your
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desaiwidget's constructor function and CSS classnames will be prefixed with the value you set `CSS_PREFIX` to.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai// Define a custom css prefix
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen DesaiMyWidget.CSS_PREFIX = "myapp-common";
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai// Inside your widget code:
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai_renderUI : function() {
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo // Generates the class name "myapp-common-selected",
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai // instead of "yui3-mywidget-selected"
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai var selectedClassName = this.getClassName("selected");
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h4>CSS Implications</h4>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>As a best practice, Widget avoids using the `style` attribute to control state such as "visible", "disabled" or "focused". Instead it marks the bounding box with class names which reflect the state:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <th>CSS Class Applied</th>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>visible</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>yui3-[widgetname]-hidden</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>disabled</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>yui3-[widgetname]-disabled</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>focused</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>yui3-[widgetname]-focused</td>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo<p>In the above definitions, "[widgetname]" is the name of the widget (e.g. "menu", "overlay", "slider").
be02c547ba97d37db2484be30f7f1510cf92a914Eric FerraiuoloThe widget name is combined with the state identifier so that different widgets can customize the way they handle visibility differently, and still work with IE6,
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desaiwhere multiple class name rules, like `.yui3-menu.yui3-hidden` are not well supported. For example:
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai/* Hide by positioning off-screen */
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai.yui3-menu-hidden {
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai top:-10000em;
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai left:-10000em;
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai/* Hide by flipping visibility */
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai.yui3-overlay-hidden {
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai visibility:hidden;
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai/* Hide by flipping display */
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai.yui3-slider-hidden {
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai display:none;
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen DesaiHowever, providing an IE6-compatible format requires each widget to ship with the CSS rules defined for each of its states.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen DesaiOf the state-based rules above, all widgets will definitely end up providing a "yui3-[widgetname]-hidden" implementation to control visibility.
f8bf159b72cbed0438d9d1d674e45fbf2d5581a9Ryuichi OkumuraWhether or not CSS rules for the other two states are provided is usually a function of whether or not the widget needs special UI handled for the "disabled" and "focused" states.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h3 id="uievents">Default UI Events</h3>
be02c547ba97d37db2484be30f7f1510cf92a914Eric FerraiuoloWidget publishes and fires custom events for any DOM events (`"click"`, `"mouseover"` etc.) which get fired inside its bounding box.
be02c547ba97d37db2484be30f7f1510cf92a914Eric FerraiuoloLike all other Widget custom events, these events are prefixed with the widget's name (e.g. 'menuitem:click') and
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolothe default context of the event listener will be the widget that fired the event (as opposed to the Node firing the DOM event).
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen DesaiThese events provide application developers the ability to listen for UI events as part of the logical widget API, without having to be concerned with the DOM elements which make up the widget's UI.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>Since these are events that many Widget instances are going to want to publish and fire, Widget does this by default to ensure that these events are fired in a performant, consistent way across Widget implementations.</p>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo Widget developers don't have to explicitly publish a given UI event in
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai order for Widget consumers to listen for them.
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo For performance, these events are only created when someone is listening, and the actual firing of these events is facilitated by a
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai single, delegated DOM event listener.
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <p>Widget developers can still choose to publish any given UI event in order to
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo explicitly control some aspect of the event.</p>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo The most likely use case is the desire to provide the default implementation/handler for a given
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo event. For example: a developer might want to publish a `"click"` event
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo for a Menu widget with the goal of providing the default click
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo The set of DOM events published by widget is defined by the
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai UI_EVENTS prototype property.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai This property defaults to <a href="{{apiDocs}}/Node.html#property_DOM_EVENTS">`Node.DOM_EVENTS`</a>.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai Widget developers can use this property to pare down or extend the number of events that are published and fired automatically.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h2 id="creatingwidgets">Developing Your Own Widgets</h2>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>To create your own widget, you'll create a class which extends `Widget` and implements the properties and methods shown in the diagram below:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p><img src="{{componentAssets}}/widget-template-diagram.png" alt="Illustration of the code template for a custom widget, showing the ATTRS property and initializer, destructor, renderUI, bindUI and syncUI methods" width="446" height="412"></p>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo<p>The best place to start is by defining the attributes which make up your widget (the `ATTRS` static property). These will help define the state and API which your widget exposes to the application developer.
be02c547ba97d37db2484be30f7f1510cf92a914Eric FerraiuoloYou can then implement the `initializer`, `destructor`, `renderUI`, `bindUI` and `syncUI` methods, based on the responsibilities defined for them above,
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desaialong with the methods which support the attribute state handling and API.</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiThe <a href="widget-extend.html">"Extending The Widget Class"</a> example walks you through the step-by-step process involved in implementing a Spinner widget using this template structure. The example along with the template file should provide a good jumping off point for developing your own widgets.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>Additionally, the template structure shown above is captured in this <a href="{{componentAssets}}/mywidget.js.txt">"MyWidget" template file</a>, which you can use as a starting point to develop your own widgets.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h2 id="pluginsandextensions">Plugins And Extensions</h2>
be02c547ba97d37db2484be30f7f1510cf92a914Eric FerraiuoloIn addition to being able to subclass any given Widget class to provide custom widget implementations, YUI 3 also provides two additional code reuse mechanisms which can be used to
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desaipackage and reuse code to provide new widgets features, without being bound to a static all-or-nothing class hierarchy.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen DesaiThese code reuse mechanisms are known as <a href="../base/#plugins"><em>Plugins</em></a> and <a href="../base/#extensions"><em>Extensions</em></a> and support for both of them is provided through Base.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>Generally widget developers should aim to provide the core set of features or functionality for any widget by sub-classing `Widget` or an existing class derived from `Widget` using `Y.extend`.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>Additional incremental features or functionality should be packaged into extensions or plugins so they can be reused across classes (in the case of extensions), or instances (in the case of plugins).</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h3 id="pluginorextension">Plugin or Extension?</h3>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>The question about whether a given piece of incremental functionality should be a Plugin or an Extension comes up frequently, and it's a design decision widget developers need to consider based on use cases for their widget.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>As mentioned above, both Plugins and Extensions provide a mechanism to write and deliver atomic, incremental pieces of functionality which add to the core implementation. Where they differ is discussed below:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt>Extensions - A Class Level Concept</dt>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <li><p>Extensions provide features which can be mixed and matched at the <strong>class</strong> level.</p></li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><p>Extensions are used by <strong>widget developers</strong> to create new widget <strong>classes</strong> which share the extension functionality.</p></li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><p>If it contains functionality which is not optional for the class, it's an extension.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>Something baked into the class, but implemented so that it can also be re-used to build other classes.</p></li>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <p><a href="widget-parentchild-listbox.html">WidgetParent, WidgetChild</a> and <a href="widget-tooltip.html">WidgetPosition, WidgetStack</a> are good examples of extensions.</p>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo A `Tree` widget class always needs Parent/Child support. However, so does a `Menu` widget class.
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo We want to reuse the Parent/Child support across both classes, without forcing them to extend a shared base class.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai Additionally, the Parent/Child functionality is a required for both classes; it is not optional.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><p>Extensions are applied to a <strong>class</strong> using the static `Base.build` method (or the `Base.create` or `Base.mix` sugar methods which sit on top of `Base.build`).</p></li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt>Plugins - An Instance Level Concept</dt>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><p>Plugins provide features which can be mixed and matched at the <strong>instance</strong> level.</p></li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><p>Plugins are used by <strong>application developers</strong> to apply features to certain <strong>instances</strong> of a widget.</p></li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><p>If it contains functionality which is not required for <em>all</em> instances of the class, it's a plugin.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>A feature which you may only want to apply to one instance, out of the ten instances of your widget on a page, is a plugin.</p></li>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <p>The <a href="../overlay/overlay-anim-plugin.html">Animation</a> and <a href="../overlay/overlay-io-plugin.html">IO</a> plugin examples are good use cases.</p>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo You don't want to have to bake Animation or IO support into a class (potentially resulting in the need to ship `MyAnimatedWidget`, `MyIOEnabledWidget`, `MyAnimatedAndIOEnabledWidget` and `MyWidget` classes).
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai The functionality is optional and can be plugged into just the <em>instances</em> of the single `MyWidget` class which need them.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><p>Plugins are applied to an <strong>instance</strong> using the instance's `plug` method.</p></li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h3 id="extensions">Widget Extensions</h3>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>As you start to develop widgets in YUI 3, there are a number of extensions packaged as part of the library which you can use with `Base.build` (or `Base.create, Base.mix`) to add functionality to your custom widget classes:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <th width="30%">Extension</th>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <th>Functionality</th>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>widget-position</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>Adds XY positioning support to the class.</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>widget-position-align</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>Adds XY aligned positioning support to the class.</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>widget-position-constrain</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>Adds constrained XY positioning support to the class.</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>widget-stack</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>Adds stacking (zIndex) support to the class.</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>widget-stdmod</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>Adds Standard Module (header, body, footer) support to the class.</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>widget-parent</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>Adds support to allow the widget to contain, manage and select child widgets.</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>widget-child</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <td>Adds support to allow the widget to be contained within a widget parent.</td>
0b3ce38e1bfc8f6ea7e23b3610172f92295ea64eEric Ferraiuolo <td>widget-buttons</td>
6ab113d0ba0aca24dcd52a6d92562955e46e5b57Eric Ferraiuolo <td>Adds header/body/footer buttons support for Widgets that use the `WidgetStdMod` extension.</td>
0b3ce38e1bfc8f6ea7e23b3610172f92295ea64eEric Ferraiuolo <td>widget-autohide</td>
0b3ce38e1bfc8f6ea7e23b3610172f92295ea64eEric Ferraiuolo <td>Adds support to hide the widget when certain DOM events occur.</td>
0b3ce38e1bfc8f6ea7e23b3610172f92295ea64eEric Ferraiuolo <td>widget-modality</td>
0b3ce38e1bfc8f6ea7e23b3610172f92295ea64eEric Ferraiuolo <td>Adds support for modality to widgets.</td>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>The functionality provided by the `widget-parent` and `widget-child` extensions, allowing widget developers to build nested widgets, is worth discussing in a little more detail:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt>widget-parent</dt>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dd>Adds support to allow the widget to contain, manage and select child widgets:
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>It provides a consistent API for creating parent/child relationships:</p>
0b3ce38e1bfc8f6ea7e23b3610172f92295ea64eEric Ferraiuolo <li><p>These can be single level relationships (e.g. Tabs in a TabList, or Buttons in a Toolbar) or nested hierarchical relationships (e.g. Menus and MenuItems, or Trees and TreeNodes).</p></li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><p>Parents are automatically set up as event targets for their children's events, allowing you to leverage custom event bubbling to listen for events higher up in the hierarchy.</p></li>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <li><p>Parents automatically render their children when rendered.</p></li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>Widget Parent augments the <a href="{{apiDocs}}/ArrayList.html">ArrayList API</a>, providing a full range of iteration and traversal methods for it's children:</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai parent.each(function(child) {...});
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><p>It also provides selection support, including support for non-binary selection states (all, none, some).</p></li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><p>Finally, it provides a sugar layer to simplify adding children to the parent during construction, by supporting an object literal format to initialize children.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai var tabview = new Y.TabView({
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai children: [{
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai label: 'foo',
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai content: '<p>foo content</p>'
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai label: 'bar',
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai content: '<p>bar content</p>'
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <dt>widget-child</dt>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <p>Adds support to allow the widget to be contained within a widget parent.</p>
be02c547ba97d37db2484be30f7f1510cf92a914Eric Ferraiuolo <p>Used together with widget-parent, allows you to support hierarchical parent/child structures. As with Widget Parent, it provides a consistent API for child widgets to
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai interact with their siblings and parents, e.g., `child.next()`, `child.previous()` and `child.ancestor()`.
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>Below are some examples showing how you can use some of these extensions:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <li>Using Extensions: <a href="widget-build.html">Building Custom Widget Classes</a></li>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <li>Widget-Position, Widget-Stack: <a href="widget-tooltip.html">A Simple Tooltip Widget</a></li>
0b3ce38e1bfc8f6ea7e23b3610172f92295ea64eEric Ferraiuolo <li>Widget-Parent, Widget-Child: <a href="widget-parentchild-listbox.html">A Hierarchical ListBox Widget</a></li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>You can also look at some of the bundled widgets which are built using extensions:</p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <li><a href="../overlay/index.html">Overlay</a><p>Uses widget-position, widget-position-align, widget-position-constrain, widget-stack, widget-stdmod</p></li>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <li><a href="../tabview/index.html">TabView</a><p>Uses widget-parent, widget-child</p></li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>The <a href="{{componentAssets}}/../base/myextension.js.txt">"MyExtension" template file</a> provides a starting point for you to create your own extensions.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<h3 id="plugins">Widget Plugins</h3>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>The YUI 3 library ships with a couple of Widget plugins for the 3.1.0 release, and also provides examples which show how you can create your own plugins:</p>
a132e5dd2d331e0abb8ddc59eac0827158d468b5Satyen Desai <li><a href="{{apiDocs}}/Plugin.WidgetAnim.html">Widget Animation Plugin</a> (api documentation)</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai <li><a href="{{apiDocs}}/Plugin.Drag.html">Widget (and Node) Drag/Drop Plugin</a> (api documentation)</li>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <li><a href="widget-plugin.html">Creating Widget Plugins</a> (example)</li>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai <li><a href="../overlay/overlay-io-plugin.html">Creating An Overlay IO Plugin</a> (example)</li>
a132e5dd2d331e0abb8ddc59eac0827158d468b5Satyen Desai <li><a href="../overlay/overlay-anim-plugin.html">Creating An Overlay Animation Plugin</a> (example)</li>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>Additionally, the YUI Gallery is another source for plugins which provide additional functionality for YUI Widgets, such as the <a href="http://yuilibrary.com/gallery/show/overlay-modal">Modal Overlay Plugin</a> and the <a href="http://yuilibrary.com/gallery/show/widget-io">Widget IO Plugin</a>.</p>
62509f008d5e74c5dfe93307eebb094e9c997f11Satyen Desai<p>The <a href="{{componentAssets}}/../plugin/myplugin.js.txt">"MyPlugin" template file</a> provides a starting point for you to create your own plugins.</p>