Issue

We have two ways of labelling skin parts in metadata: required and optional.  But there are really three distinct classifications we care about:

  1. this part is something that is core to the definition of the component, so much so that it would be non-sensical not to have it.  The tool should make that clear to designers.  And the part must exist at all times, in all states.
  2. This part is core to the definition of the component, as above.  But we expect that it might be something that will come and go, in different states, and have written our code to accomodate that.
  3. This part is optional.  The component can functional perfectly well without it, and our code is written to accomodate its presence or absence at different times.
  4. (there are other, more nuanced classifcations, but we get diminishing returns trying to tease them out).

With three classifications, and only two ways of labelling a skin part, how do we map them? And what is our philosophy for what kinds of skin parts we should be creating?

Resolving the classifications

  1. There is no need to distinguish between 2 and 3, above.  If a component can handle a part being absent, call it optional. This option gives less information to the tool about what is 'core' to the component.
  2. We should never require a part to be present at all times.  required vs. optional is really a tool hint, but components should always guard against missing parts.  This makes 'required' vs. 'optional' nothing more than tooling hints, and puts the burden on the component developer to make their code more defensive.
  3. introduce a third label on SkinPart metadata: 'suggested' (bad name, but you get the idea).  Then 'required' continues to mean it must be present at all times, 'suggested' means it's a core part of the component, but can come and go, and 'optional' means it can come and go, and provides secondary behavior.

Our Philosophy

We should aim to make our components as flexible as possible. Well behaved component developers should give users the greatest flexibility, and that means never making a component truly 'required.'  Regardless of which option we choose, our philosophy should always be to allow skin parts to come and go, except in specific exceptions.

Proposal

Just as we should be making our components as flexible as possible, we should be encouraging 3rd parties to do the same.  Having SkinnableComponents, by default, force skinners to define all parts in all states is encouraging bad behavior.  Instead, we should encourage flexible components, and allow that developers can write 'lazy' code for use cases where they know the part will always exist.  For example, we don't throw an error when someone forgets to assign explicit width/height to a component that doesn't have a measure routine.  We should be following the same philosophy here. Specifically:

  1. change the default behavior of the SkinPart metadata to match the required="false" behavior.
  2. Schedule a review of the types of our Skin Parts, to make sure our contracts are as general as possible (including introducing new intermediary types if necessary).  This will mitigate the impact of a required part by allowing developers the most freedom to replace a part with an alternate implementation.
  3. review our skin parts defined in Spark to make sure that all required parts are intentionally so, rather than because of lack of consideration. Specifically, the following additional skin parts should be made optional:
  • Panel.titleFIeld
  • Scroller.horizontalScrollbar
  • Scroller.verticalScrollbar
  • SkinnableDataContainer.dataGroup
  • TextBase.textView
  • TrackBase.thumb
  • TrackBase.track

That would leave the following parts required:

  • ButtonBar.middleButton
  • DropDownList.openButton
  • NumericStepper.textInput
  • SkinnableContainer.contentGroup
  • Spinner.incrementButton
  • Spinner.decrementButton
  • Titlebar.closeButton
  • VideoPlayer.videoElement
You must be logged in to comment.