How would we build a
Button that can be set up as part of
ButtonGroup? Typically in raw CSS or with
preprocessors, this is accomplished by using sibling
selectors, etc. With the
styled API and React* ecosystem
style approach, we can take a different approach that
separates grouping logic from style rendering.
In Bootstrap, the user-side API looks like this:
and you can find the relevant SCSS on GitHub
With emotion we'll try to get an API that looks like this:
Since this isn't about a11y or other abstractions we'll just leave them there as passthroughs with the note that there are nice ways to require these properties using PropTypes or Flow or even abstract them into the component. We are trying to compare directly to the Bootstrap API here, although we could do better in a couple aspects.
First, we'll need a styled button that uses props to dictate it's border-radius. We'll be using border-radius as the example attribute rather than a full exposition of attributes to keep the example code small.
In this example, we are using the
groupPosition prop to
dictate whether we alter the
border-radius values for
being first in the list, last in the list or in the middle
of the list. We also set a final value which is used if the
Button is not in a list at all.
In the following
ButtonGroup we use React Children APIs to
clone the child and apply our
groupPosition prop. (Here is
the link for
if you are unfamiliar with it.
We can render our new Buttons as such:
The core point here is that the
Button knows how to render
itself stylistically in every situation it would be
rendered. There are no overrides so we can debug more easily
and co-locating all of the styling means we are less likely
to forget that the Navigation in that one app has specific
overrides. This means we can evolve our
Button API with
more confidence since it places global overrides distinctly
in the region of unsupported APIs.
ButtonGroup can control the ordering and grouping of
Buttons with it's own props, like
vertical, if we
want more flexibility. Changing the
Button so that it can
render vertically will take us right back to the same spot
we are defining the logic for other rendering arrangements
so we can take it all into consideration when evolving our