I'm pleased to announce a new milestone for delite, deliteful and requirejs-dplugins as well as a few other projects.
Here are a few highlights about this release:
- We are now consistently using ES6 Promises across the various projects. We achieved that through the
Promise
plugin of the requirejs-dplugins project which delegates either
to the native ES6 implementation or to the Lie JavaScript implementation
depending on native browser support presence.
- We extended the use of jQuery for DOM manipulation from delite to deliteful.
- We also added a first delite tutorial on how to build you own custom element widget with delite.
- We improved documentation and added a documentation page on styling deliteful elements
- We have various bidirectional text improvements both at delite & deliteful level.
- Combobox is finally converging with keyboard support as well as multi channel policy support based on the new
channelBreakpoints module that allows you to define the default breakpoints used in the application.
- There were various cleanups on form widget base classes as well as on the CSS of the deliteful widgets (more to come)
- We now have in the handlebars plugin a requireAndCompile() method for code that needs to load the templates manually
rather than using handlebars! as a plugin
As you might have noticed we did not add new custom elements in this milestone and we concentrated on consolidating
what existed before. Hopefully next milestone should bring us new widgets like TabBar or
DropDown button/menu.
Thanks to anyone that contributed to this milestone, in particular, Adrian, Bill, Clement, Damien, Ed, Lee, Semion and Youcef!
Note that we have a number of incompatibilities:
- at delite level, the move to ES6 Promise has forced changes on the
delite-display-load
event API for DisplayContainer
- still for delite, the
Widget.startup()
method has been deprecated. For programmatically created widgets we encourage
you to use placeAt()
instead.
- HasDropDown no longer sets CSS classes for the arrow direction
- at deliteful level, the SwapView viewstack property has been renamed to viewStack (camel case).
If you need more details please checkout the delite &
deliteful release notes on github.
Right in time for the week-end, we have new releases to announce, we actually tagged a 0.5.0 a few days ago but as
we found a blocker issue when running cross-domain right after release, we came up shortly after with 0.5.1.
As usual just use bower to install the latest release:
Among the new features or enhancements of this release you will find:
- SwapView, a container custom element extending
ViewStack
to provide interaction in order to navigate between the various stacked views
- ViewIndicator a simple element enumerating the
views of a
ViewStack
and displaying which one is currently visible.
- additional improvements to Combobox element even
though we did not managed to complete all what we had in mind
(more to come in 0.6.0).
- use of jQuery Core for DOM manipulation in delite.
- upgrade store management to dstore 1.0
- as part of the requirejs-dplugins 0.4.0 release, we added a nice
jquery
AMD plugin. If jQuery is not already present in your application, requiring a jQuery AMD module will actually load the
AMD module. Conversely if jQuery has already loaded in your application as a single JavaScript file, requiring a
jQuery AMD module will do nothing and just use the already loaded jQuery. This is used by the delite work above.
- finally as part of the ecma402 0.2.6 release we leveraged navigator.languages
when available to pick the best locale.
Read more...
Since delite's inception we are leveraging Web Components and in particular Custom Elements specification. We are pretty happy with this choice that I exposed in my introducing blog post and we hope this common Web extension mechanism will bring interoperability between the various UI frameworks & widget sets on the mid/long term.
That said we are sometimes facing some limitations with custom elements that are annoying and might slow down its adoption. I wanted to highlight two of them in this blog post, hoping to bring some more awareness around those.
The most common one, that was already mentioned by others in the past, is the lack of namespacing or scoping for the elements. Let's say someone comes up with a d-list
custom element just as we did, then any application developer bringing the two pieces of JavaScript in the application will have a clash between the two elements. Fortunately an error will be thrown when the second element is registered and some workarounds at application level like redefinition of the Document.registerElement()
method can deal with that. However that workarounds are not satisfactory as they don't really solve the root issue of the specification giving room to potential registration clashes.
This lack of namespace management is kind of contradicting what I think should be the ultimate custom element role, that is interoperability.
For now we have decided to not deal with that issue at delite level except by using the d-
prefix for all our components and hoping nobody else will use that same prefix.
Another less common limitation that we faced recently is the two steps process of custom elements interpretation. The elements are first seen as HTMLUnknownElement
, and as soon as Document.registerElement()
has been called they are upgraded to actual HTMLElement
of their declared type. There are two issues behind that:
- this process easily happens asynchronously (i.e.
Document.registerElement()
is called when the corresponding element JavaScript happens to be loaded so in an order you don't necessarily control depending on your application setup)
- during its creation/attachment process a given custom element might need to reach out other elements.
For example:
<my-data-store-element id="a-data-store-element"></my-data-store-element>
<my-ui-element ref="a-data-store-element"></my-ui-element>
will certainly have code like the following in my-ui-element
implementation:
attachedCallback: function () {
var store = element.ownerDocument.getElementById(this.getAttribute("ref"));
// get information and stuff on the store element
}
Depending on the indeterminate timing that custom elements are downloaded and registered, and my-ui-element.attachedCallback()
might try to access the a-data-store-element
before it has actually been upgraded to a custom element. For this reason the store element might not be "ready" to be used leading to incorrect setup of my-ui-element
.
For this reason it would be useful to be notified when an element has really been created (and attached) as an actual custom element so that other elements can react to this.
This one was actually hurting us in a very similar situation to the one I described just above. See for example:
where d-list
element connects to a d-store
element.
As this was blocking us we decided to not wait on a possible specification improvement as for the namespace issue and at least for now implement our own mechanism. The solution here was to dispatch a "customelement-attached"
event after execution of the attachedCallback
of any delite element. This allows an element to wait for another element to have been upgraded to custom element and attached.
You can then modify the attachedCallback()
above as follows:
attachedCallback: function () {
var store = element.ownerDocument.getElementById(this.getAttribute("ref"));
if (store instanceof HTMLElement) {
// get information and stuff on the store
} else {
// wait for it to be ready and proceed
store.addEventListener("customelement-attached", function () {
// get information and stuff on the store
});
}
}
Ideally I think this should not be a delite-specific event but that Custom Elements specification should provide a similar event so that created & attached callback can notify other elements of their execution.
What do you think? Is that something you see missing in Custom Elements specification or is that just me needing this event to coordinate elements creation & attachment?
Read more...
As announced in this previous post,
the deliteful project now includes a preview of
the ComboBox widget.
This post aims to:
- Explain how the new widget complements the existing
Select widget.
- Provide a guidance about the criteria for choosing which of the two widgets fits better
depending on application needs.
The widgets Combobox
(custom tag: d-combo-box
) and Select
(custom tag: d-select
)
share a number of characteristics:
- Allow to select one or more items among a number of options (in single or multiple
selection modes).
- Benefit from delite's
CustomElement and
Widget infrastructure.
- Store-based: render data provided by a data store object.
- Form-aware: inherit from FormWidget.
- Multi-channel responsive: they render differently on mobile than desktop, thus
providing a user-experience adapted to each. (For
Combobox
, among other improvements
that will come in a future release, the multi-channel policy and in particular its
configurability will be revisited; see delite #366).
- Can be used both programmatically and in markup (including for specifying the options,
thanks to the new
d-store
custom element.
The two widgets also differ by other features; only Combobox
provides:
Read more...