Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

feat(Button): added ButtonGroup component #179

Merged
merged 10 commits into from
Sep 6, 2018
Merged

Conversation

mnajdova
Copy link
Contributor

@mnajdova mnajdova commented Sep 4, 2018

ButtonGroup

The ButtonGroup component, as part of the Button component, will be used to organize multiple buttons to apear together.

TODO

  • Conformance test
  • Minimal doc site example
  • Stardust base theme
  • Teams Light theme
  • Teams Dark theme
  • Teams Contrast theme
  • Confirm RTL usage
  • W3 accessibility check
  • Stardust accessibility check
  • Update glossary props table
  • Update the CHANGELOG.md

API Proposal

as?: any

children?: ReactChildren

circular?: boolean

This property is used for creating group of circular buttons

image

<Button.Group
    circular
    buttons={[
      { icon: 'book', type: 'primary' },
      { icon: 'coffee' },
      { icon: 'play', type: 'primary' },
    ]}
  />
<div class="ui-buttons">
  <button class="ui-button ..." aria-disabled="false">
    <span class="ui-icon ..." aria-hidden="true"></span>
  </button>
  <button class="ui-button ..." aria-disabled="false">
    <span class="ui-icon ..." aria-hidden="true"></span>
  </button>
  <button class="ui-button ..." aria-disabled="false">
    <span class="ui-icon ..." aria-hidden="true"></span>
  </button>
</div>

className?: string

content?: React.ReactNode

buttons?: ItemShorthand[]

Shorthand for setting the buttons that should appear in the group.

image

<Button.Group buttons={[{ icon: 'book', iconOnly: true }, { icon: 'coffee', iconOnly: true }, { icon: 'play', iconOnly: true }]} />
<div class="ui-buttons">
  <button class="ui-button ..." aria-disabled="false">
    <span class="ui-icon ..." aria-hidden="true"></span>
  </button>
  <button class="ui-button ..." aria-disabled="false">
    <span class="ui-icon ..." aria-hidden="true"></span>
  </button>
  <button class="ui-button..." aria-disabled="false">
    <span class="ui-icon ..." aria-hidden="true"></span>
  </button>
</div>

styles?: IComponentPartStylesInput

variables?: ComponentVariablesInput

Question

Do we have mechanism for testing collectionShorthand (list of itemShorthand). If not, should I create one and use for testing the buttons inside the ButtonGroup component?

@codecov
Copy link

codecov bot commented Sep 4, 2018

Codecov Report

Merging #179 into master will increase coverage by 0.6%.
The diff coverage is 84.21%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master     #179     +/-   ##
=========================================
+ Coverage   67.09%   67.69%   +0.6%     
=========================================
  Files         101      103      +2     
  Lines        1407     1461     +54     
  Branches      290      288      -2     
=========================================
+ Hits          944      989     +45     
- Misses        459      468      +9     
  Partials        4        4
Impacted Files Coverage Δ
.../themes/teams/components/Button/buttonVariables.ts 66.66% <ø> (ø) ⬆️
src/components/List/List.tsx 100% <ø> (ø) ⬆️
src/themes/teams/components/Button/buttonStyles.ts 11.42% <0%> (-0.34%) ⬇️
src/components/Button/index.ts 100% <100%> (ø) ⬆️
src/index.ts 100% <100%> (ø) ⬆️
src/components/Button/Button.tsx 95.55% <100%> (+0.31%) ⬆️
src/themes/teams/componentVariables.ts 100% <100%> (ø) ⬆️
src/themes/teams/componentStyles.ts 100% <100%> (ø) ⬆️
...hemes/teams/components/Button/buttonGroupStyles.ts 30% <30%> (ø)
src/components/Button/ButtonGroup.tsx 97.29% <97.29%> (ø)
... and 3 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5277076...9453d62. Read the comment docs.

@mnajdova mnajdova added the RFC label Sep 4, 2018
@layershifter
Copy link
Member

layershifter commented Sep 4, 2018

@mnajdova we don't have common tests for collections in SUIR, so I think that Stardust doesn't have them, too.

@mnajdova
Copy link
Contributor Author

mnajdova commented Sep 5, 2018

Got it, thanks @layershifter, will add one common test for the collectionShorthand.

-updated ButtonGroup-test.tsx to confirm to the collection shorthand test
expect(Component.propTypes[shorthandPropertyName]).toBeTruthy()
})

test(`array of string values are handled as ${
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grammar nit: 'as' -> 'is' :)

Copy link
Contributor

@kuzhelov kuzhelov Sep 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would also recommend to consider test renaming, to better indicate what is going on, something like 'array of string values is spread as ...'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, it is better explained that way!

const props = { [shorthandPropertyName]: shorthandValue }
const wrapper = mount(<Component {...props} />)

const shorthandComponentProps = wrapper.find(ShorthandComponent.displayName)
Copy link
Contributor

@kuzhelov kuzhelov Sep 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems that name of the variable is not correct - due to wrapper.find(ShorthandComponent.displayName) returns a nodes wrapper, not props

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the catch! I changed it in the other test and forgot about this one.. :)

_.first(shorthandValue),
).every(
propertyName =>
propertyName === 'key'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be simplified

propertyName => propertyName === 'key' || _.first(shorthandValue)[propertyName] === shorthandComponents.first().prop(propertyName)


describe('ButtonGroup', () => {
isConformant(ButtonGroup)
buttonGroupImplementsShorthandProp('buttons', Button)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

src/index.ts Outdated
@@ -3,6 +3,7 @@ export { themes }

export { default as Accordion } from './components/Accordion'
export { default as Button } from './components/Button'
export { ButtonGroup } from './components/Button'
export { default as Chat } from './components/Chat'
export { default as ChatMessage } from './components/Chat'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems that we have a problem here - as Chat is exported as ChatMessage. Could you, please, fix this? :)

@@ -6,6 +6,7 @@ export interface IButtonVariables {
height: string
minWidth: string
maxWidth: string
defaultBorderRadius: string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we using any different other than default one for Button? If not, we should probably consider to rename it to something like just borderRadius - what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we have circularRadius as well, that is why this is named like that.

class ButtonGroup extends UIComponent<Extendable<IButtonGroupProps>, any> {
public static displayName = 'ButtonGroup'

public static className = 'ui-button__buttons'
Copy link
Contributor

@kuzhelov kuzhelov Sep 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems that BEM conventions are violated here - this reads as 'buttons' element inside 'ui-button' - but I would rather expect something simpler like 'ui-buttons' or 'ui-button-group'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have utility function for generating the className inside getComponentInfo.ts:

info.componentClassName = (info.isChild
? `ui-${info.parentDisplayName}__${info.subcomponentName.replace(
/Group$/,
`${info.parentDisplayName}s`,
)}`
: `ui-${info.displayName}`
).toLowerCase()

I was just following it in order to make the component conformant. Do you think we should change this logic?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the logic of this function seems correct to me - the problem is that for info.parentDisplayName 'button' is used for the case of ButtonGroup, and this is semantically incorrect

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the end, we decided that the components that contain Group inside the name should result into the main components class with appended 's' in the end (For the ButtonGroup it should be ui-buttons). We are doing this because we already had some logic for the Group components, and we can still keep the group components together with the main components that they represent.

)
}

getStyleForButtonIndex = (styles, buttons, idx) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems that logic of this function relies (semantically) only on isFirst and isLast flags - for the sake of making its interface lighter and more explicit, could we introduce these two instead of buttons and idx?

Button.create(button, {
defaultProps: {
circular,
styles: { root: this.getStyleForButtonIndex(styles, buttons, idx) },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this showcases the problem we currently have for variables as well (#162) - with current implementation approach we will have the same negative consequences for styles as the ones described there for variables. Lets consider to address this moment later

Copy link
Contributor

@kuzhelov kuzhelov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please, take a look on comments before merging - nothing critical, though. Awesome job with introducing implementsCollectionShorthandProp 👍

manajdov added 2 commits September 6, 2018 11:54
# Conflicts:
#	CHANGELOG.md
#	test/specs/components/Menu/Menu-test.tsx
@mnajdova mnajdova merged commit 4697975 into master Sep 6, 2018
@levithomason levithomason deleted the feat/button-group branch October 29, 2019 22:30
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants