Hmmmmm... why not use a subset of CSS syntax? Define CSS classes inline
or in stylesheets and define class attributes on elements? Kinda like
html.
Cheers,
Michael
On Wed, 30 Jun 2010, Greg Brown wrote:
Hi all,
I have recently been giving some thought to how we might support a form
of style propagation. This has come up a few times and is clearly a
feature that developers would like the platform to provide.
By design, Pivot does not currently support style inheritance. We
decided up front that there is not enough commonality between component
and container styles for such an inheritance mechanism to make sense.
What does make sense, however, is the concept of "named styles". These
are similar in concept to CSS classes - they would allow a caller to
specify a set of styles by name that should be applied to a component.
For example, all Labels associated with the "boldLabel" named style
would be bold.
Pivot currently supports a rudimentary form of named styles via the
URL-based styles setter:
<Label styles="@my_label_styles.json"/>
There are a couple of downsides to this approach, though:
- It requires designers to split their style definitions into many small
files.
- It only allows the designer to apply a single set of styles; style
sets cannot be combined (e.g. "apply both my_styles1.json and
my_styles2.json"), nor can they be overridden on a per-component basis
by applying local styles (e.g. "apply my_styles.json and {foo:'bar'}").
I have a proposed solution and I would like to hear your feedback on it.
I suggest that we add a "namedStyles" property at the Container level.
This property would be a read-only dictionary mapping style group names
to maps of style properties:
Container {
NamedStyleDictionary : Dictionary<String, Map<String, ?>>
}
These styles could be referred to by child components of the container.
For example, the following would create a "boldLabel" style at the
Window level and apply it to the window's content:
<Window namedStyles="{boldLabel:{font:{bold:true}}}">
<Label styles="boldLabel"/>
</Window>
Named styles could be combined as well as augmented on a per-component
basis by local styles:
<Label styles="boldLabel, redLabel, {backgroundColor:'#00ff00'}"/>
Additionally, nested container could override styles defined by an
ancestor:
<Window namedStyles="{myLabel:{color:'#ff0000'}}">
<BoxPane namedStyles="{myLabel:{color:'#0000ff'}}">
<!-- Label text will be blue -->
<Label styles="myLabel"/>
</BoxPane>
</Window>
Finally, named styles could be stored externally and loaded via URL or
resource path:
<Window namedStyles="@my_styles.json">
...
</Window>
<Window namedStyles="com/foo/my_styles.json">
...
</Window>
Overall, I think the approach works well. It addresses the major issues
that have been raised and does so in a manner that is consistent with
other aspects of BXML and WTK. There is only one aspect of the design
that I am not 100% happy with - supporting a simple "namedStyles"
attribute would only allow the developer to include a single named
styles definition per container. In practice, this is probably
sufficient, but it would be nice to support multiple style sheets if
possible. My proposed solution to this is as follows:
<Window>
<namedStyles buttons="@button_styles.json"
labels="{color:'#ff0000'}"/>
...
</Window>
This would be the equivalent of the following style sheet applied via
the "namedStyles" attribute:
{ buttons: {
// content of button_styles.json
},
labels: {
color: "#ff0000"
}
}
This syntax could be supported in addition to, or instead of, the
attribute syntax.
Please let me know what you think of this possible approach.
Thanks,
Greg