-
Notifications
You must be signed in to change notification settings - Fork 4k
refactor(Button): rework labeled for consistency with Input #510
Description
At the time of writing the Input API is in progress at #281. The button API is already complete. This issue was started to keep consistency between the labeled APIs of these two components.
Issue
The Input component can accept a label or an action on the left or right of the <input />. If children are used for configuring the label or action (as in the Button) then the children must be parsed and the <input /> must be inserted into the children at the correct place. Identifying and parsing children is not a practical solution.
Solution
The best way to deal with this relationship is via props. We'll leverage shorthand prop values (literal, props object, element instance) to construct labeled markup.
Refactors
I've taken some doc examples and refactored them to show the new API. Notable changes:
<Button labeled />goes away. It currently renders aui labeled buttonwrapper.- Button children will always be the primary content of the button
labeled='left|right'is nowlabelPosition
I've shown the shortest syntax for the examples below. Though, keep in mind that all shorthand props can take a primitive value, a props object, or an element instance. You can of course organize (unusually rare) complicated label/icon markup into a separate render function and call it there as well. This retains full control over the markup for the user.
ButtonLabeledExample.js
<Button labeled>
<Button>
<Icon name='heart' /> Like
</Button>
<Label as='a' basic>2,048</Label>
</Button>
<Button labeled='left'>
<Label as='a' basic pointing='right'>2,048</Label>
<Button>
<Icon name='heart' /> Like
</Button>
</Button>
<Button labeled='left'>
<Label as='a' basic>2,048</Label>
<Button icon>
<Icon name='fork' />
</Button>
</Button><Button
content='Like'
icon='heart'
label={{ as: 'a', basic: true, content: '2,048' }}
/>
<Button
content='Like'
icon='heart'
label={{ as: 'a', basic: true, pointing: 'right', content: '2,048' }}
labelPosition='left'
/>
<Button
icon='fork'
label={{ as: 'a', basic: true, content: '2,048' }}
labelPosition='left'
/>ButtonLabeledIconExample.js
<Button labeled icon>
<Icon name='pause' /> Pause
</Button>
<Button labeled='right' icon>
<Icon name='right arrow' /> Next
</Button><Button icon='pause' labelPosition='left' content='Pause' />
<Button icon='right arrow' labelPosition='right' content='Next' />Conclusion
This API is necessary for the Input. An Input should never have children, as the current labeled Button API precedent would suggest. We think consistency across all components is extremely important. So, the Button should also use the same labeled API.
After several offline chats, we also think it just makes more sense this way. A Button should always render a Button. Its children should always be the button content. Instead of the current state, where it sometimes renders a ui labeled button container that accepts a Button as a child, which renders an actual button. This is strange and unintuitive.