Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Add `avatar` prop to `Chat.Message` subcomponent @Bugaa92 ([#159](https://github.com/stardust-ui/react/pull/159))
- add `iconOnly` prop to `Button` @mnajdova ([#182](https://github.com/stardust-ui/react/pull/182))
- Add Label `image` and `imagePosition`, removed `onIconClick` prop @mnajdova ([#55](https://github.com/stardust-ui/react/pull/55/))
- Add `ButtonGroup` component @mnajdova ([#179](https://github.com/stardust-ui/react/pull/179))

<!--------------------------------[ v0.5.0 ]------------------------------- -->
## [v0.5.0](https://github.com/stardust-ui/react/tree/v0.5.0) (2018-08-30)
Expand Down
9 changes: 4 additions & 5 deletions build/gulp/plugins/util/getComponentInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,12 @@ const getComponentInfo = filepath => {
: info.displayName

// class name for the component
// example, the "button" in class="ui button"
// example, the "button" in class="ui-button"
// name of the component, sub component, or plural parent for sub component groups
info.componentClassName = (info.isChild
? `ui-${info.parentDisplayName}__${info.subcomponentName.replace(
/Group$/,
`${info.parentDisplayName}s`,
)}`
? _.includes(info.subcomponentName, 'Group')
? `ui-${info.parentDisplayName}s`
: `ui-${info.parentDisplayName}__${info.subcomponentName}`
: `ui-${info.displayName}`
).toLowerCase()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'
import { Button } from '@stardust-ui/react'

const ButtonGroupCircularExampleShorthand = () => (
<Button.Group
circular
buttons={[
{ icon: 'book', type: 'primary' },
{ icon: 'coffee' },
{ icon: 'play', type: 'primary' },
]}
/>
)

export default ButtonGroupCircularExampleShorthand
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react'
import { Button } from '@stardust-ui/react'

const ButtonGroupExampleShorthand = () => (
<Button.Group
buttons={[
{ icon: 'book', iconOnly: true },
{ icon: 'coffee', iconOnly: true },
{ icon: 'play', iconOnly: true },
]}
/>
)

export default ButtonGroupExampleShorthand
20 changes: 20 additions & 0 deletions docs/src/examples/components/Button/Groups/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'
import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'

const Groups = () => (
<ExampleSection title="Groups">
<ComponentExample
title="Group"
description="Buttons can exist together as a group."
examplePath="components/Button/Groups/ButtonGroupExample"
/>
<ComponentExample
title="Circular group"
description="Buttons inside a group can be styled as circular."
examplePath="components/Button/Groups/ButtonGroupCircularExample"
/>
</ExampleSection>
)

export default Groups
2 changes: 2 additions & 0 deletions docs/src/examples/components/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import React from 'react'
import Types from './Types'
import Variations from './Variations'
import States from './States'
import Groups from './Groups'

const ButtonExamples = () => (
<div>
<Types />
<States />
<Variations />
<Groups />
</div>
)

Expand Down
9 changes: 8 additions & 1 deletion src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as PropTypes from 'prop-types'
import * as React from 'react'

import { UIComponent, childrenExist, customPropTypes } from '../../lib'
import { UIComponent, childrenExist, customPropTypes, createShorthandFactory } from '../../lib'
import Icon from '../Icon'
import { ButtonBehavior } from '../../lib/accessibility'
import { Accessibility } from '../../lib/accessibility/interfaces'
Expand All @@ -12,6 +12,7 @@ import {
ReactChildren,
ComponentEventHandler,
} from '../../../types/utils'
import ButtonGroup from './ButtonGroup'

export interface IButtonProps {
as?: any
Expand Down Expand Up @@ -43,6 +44,8 @@ export interface IButtonProps {
* - if button includes icon only, textual representation needs to be provided by using 'title', 'aria-label', or 'aria-labelledby' attributes
*/
class Button extends UIComponent<Extendable<IButtonProps>, any> {
static create: Function

public static displayName = 'Button'

public static className = 'ui-button'
Expand Down Expand Up @@ -121,6 +124,8 @@ class Button extends UIComponent<Extendable<IButtonProps>, any> {
accessibility: ButtonBehavior as Accessibility,
}

static Group = ButtonGroup

public renderComponent({
ElementType,
classes,
Expand Down Expand Up @@ -179,4 +184,6 @@ class Button extends UIComponent<Extendable<IButtonProps>, any> {
}
}

Button.create = createShorthandFactory(Button, content => ({ content }))

export default Button
118 changes: 118 additions & 0 deletions src/components/Button/ButtonGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import * as PropTypes from 'prop-types'
import * as React from 'react'
import * as _ from 'lodash'

import { UIComponent, childrenExist, customPropTypes } from '../../lib'
import { ComponentVariablesInput, IComponentPartStylesInput } from '../../../types/theme'
import { Extendable, ItemShorthand, ReactChildren } from '../../../types/utils'
import Button from './Button'

export interface IButtonGroupProps {
as?: any
children?: ReactChildren
circular?: boolean
className?: string
content?: React.ReactNode
buttons?: ItemShorthand[]
styles?: IComponentPartStylesInput
variables?: ComponentVariablesInput
}

/**
* A button group.
*/
class ButtonGroup extends UIComponent<Extendable<IButtonGroupProps>, any> {
public static displayName = 'ButtonGroup'

public static className = 'ui-buttons'

public static propTypes = {
/** An element type to render as (string or function). */
as: customPropTypes.as,

/** A button can take the width of its container. */
buttons: customPropTypes.collectionShorthand,

/** Primary content. */
children: PropTypes.node,

/** Additional classes. */
className: PropTypes.string,

/** The buttons inside group can appear circular. */
circular: PropTypes.bool,

/** Shorthand for primary content. */
content: customPropTypes.contentShorthand,

/** Custom styles to be applied for component. */
styles: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),

/** Custom variables to be applied for component. */
variables: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
}

static handledProps = [
'as',
'buttons',
'children',
'circular',
'className',
'content',
'styles',
'variables',
]

public static defaultProps = {
as: 'div',
}

public renderComponent({
ElementType,
classes,
accessibility,
variables,
styles,
rest,
}): React.ReactNode {
const { children, content, buttons, circular } = this.props
if (_.isNil(buttons)) {
return (
<ElementType {...rest} className={classes.root}>
{childrenExist(children) ? children : content}
</ElementType>
)
}

return (
<ElementType {...rest} className={classes.root}>
{_.map(buttons, (button, idx) =>
Button.create(button, {
defaultProps: {
circular,
styles: {
root: this.getStyleForButtonIndex(styles, idx === 0, idx === buttons.length - 1),
},
},
}),
)}
</ElementType>
)
}

getStyleForButtonIndex = (styles, isFirst, isLast) => {
let resultStyles = {}
if (isFirst) {
resultStyles = styles.firstButton
}
if (isLast) {
resultStyles = { ...resultStyles, ...styles.lastButton }
}
if (!isFirst && !isLast) {
resultStyles = styles.middleButton
}
return resultStyles
}
}

export default ButtonGroup
1 change: 1 addition & 0 deletions src/components/Button/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default } from './Button'
export { default as ButtonGroup } from './ButtonGroup'
2 changes: 1 addition & 1 deletion src/components/List/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class List extends UIComponent<Extendable<IListProps>, any> {
debug: PropTypes.bool,

/** Shorthand array of props for ListItem. */
items: PropTypes.arrayOf(PropTypes.any),
items: customPropTypes.collectionShorthand,

/** A selection list formats list items as possible choices. */
selection: PropTypes.bool,
Expand Down
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ 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'
export { ChatMessage } from './components/Chat'
export { default as Divider } from './components/Divider'
export { default as Grid } from './components/Grid'
export { default as Image } from './components/Image'
Expand Down
1 change: 1 addition & 0 deletions src/themes/teams/componentStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export { default as AccordionTitle } from './components/Accordion/accordionTitle
export { default as Avatar } from './components/Avatar/avatarStyles'

export { default as Button } from './components/Button/buttonStyles'
export { default as ButtonGroup } from './components/Button/buttonGroupStyles'

export { default as Chat } from './components/Chat/chatStyles'
export { default as ChatMessage } from './components/Chat/chatMessageStyles'
Expand Down
1 change: 1 addition & 0 deletions src/themes/teams/componentVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export { default as AccordionContent } from './components/Accordion/accordionCon
export { default as Avatar } from './components/Avatar/avatarVariables'

export { default as Button } from './components/Button/buttonVariables'
export { default as ButtonGroup } from './components/Button/buttonVariables'

export { default as ChatMessage } from './components/Chat/chatMessageVariables'

Expand Down
32 changes: 32 additions & 0 deletions src/themes/teams/components/Button/buttonGroupStyles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { IComponentPartStylesInput, ICSSInJSStyle } from '../../../../../types/theme'
import { IButtonGroupProps } from '../../../../components/Button/ButtonGroup'

const commonButtonsStyles = (circular: boolean) => ({
...(!circular && {
margin: '0px',
borderRadius: '0px',
}),
})

const buttonGroupStyles: IComponentPartStylesInput = {
root: (): ICSSInJSStyle => ({}),
middleButton: ({ props: p }: { props: IButtonGroupProps; variables: any }) => ({
...commonButtonsStyles(p.circular),
}),
firstButton: ({ props: p, variables: v }: { props: IButtonGroupProps; variables: any }) => ({
...commonButtonsStyles(p.circular),
...(!p.circular && {
borderTopLeftRadius: v.borderRadius,
borderBottomLeftRadius: v.borderRadius,
}),
}),
lastButton: ({ props: p, variables: v }: { props: IButtonGroupProps; variables: any }) => ({
...commonButtonsStyles(p.circular),
...(!p.circular && {
borderTopRightRadius: v.borderRadius,
borderBottomRightRadius: v.borderRadius,
}),
}),
}

export default buttonGroupStyles
3 changes: 2 additions & 1 deletion src/themes/teams/components/Button/buttonStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const buttonStyles: IComponentPartStylesInput = {
height,
minWidth,
maxWidth,
borderRadius,
color,
backgroundColor,
backgroundColorHover,
Expand All @@ -33,14 +34,14 @@ const buttonStyles: IComponentPartStylesInput = {
maxWidth,
color,
backgroundColor,
borderRadius,
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
position: 'relative',
padding: `0 ${pxToRem(paddingLeftRightValue)}`,
margin: `0 ${pxToRem(8)} 0 0`,
verticalAlign: 'middle',
borderRadius: pxToRem(2),

borderWidth: `${secondary ? (circular ? 1 : 2) : 0}px`,
cursor: 'pointer',
Expand Down
2 changes: 2 additions & 0 deletions src/themes/teams/components/Button/buttonVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface IButtonVariables {
height: string
minWidth: string
maxWidth: string
borderRadius: string
color: string
backgroundColor: string
backgroundColorHover: string
Expand All @@ -26,6 +27,7 @@ export default (siteVars: any): IButtonVariables => {
height: pxToRem(32),
minWidth: pxToRem(96),
maxWidth: pxToRem(280),
borderRadius: pxToRem(2),
color: siteVars.black,
backgroundColor: siteVars.gray08,
backgroundColorHover: siteVars.gray06,
Expand Down
Loading