This repository has been archived by the owner on Mar 4, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Toolbar): add
custom
kind of ToolbarItem (#1558)
* feat(Toolbar) - add `custom` kind of item * simplify example * add mention about `custom` kind * add `focusable` prop, update warning and example * fix classname * fix UTs * add changelog entry * fix changelog entry * update message
- Loading branch information
1 parent
ee412c7
commit 9e11693
Showing
13 changed files
with
268 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
docs/src/examples/components/Toolbar/Content/ToolbarExampleCustomContent.shorthand.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import * as React from 'react' | ||
import { Button, Text, Toolbar } from '@stardust-ui/react' | ||
|
||
const ToolbarExampleCustomContentShorthand = () => ( | ||
<Toolbar | ||
items={[ | ||
{ key: 'bold', icon: 'bold' }, | ||
{ | ||
key: 'custom-text', | ||
content: <Text content="Text" />, | ||
kind: 'custom', | ||
}, | ||
{ | ||
key: 'custom-focusable-text', | ||
content: <Text content="Focusable" />, | ||
focusable: true, | ||
kind: 'custom', | ||
}, | ||
{ | ||
key: 'custom-button', | ||
kind: 'custom', | ||
content: <Button content="Button" />, | ||
fitted: 'horizontally', | ||
}, | ||
]} | ||
/> | ||
) | ||
|
||
export default ToolbarExampleCustomContentShorthand |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
packages/react/src/components/Toolbar/ToolbarCustomItem.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import * as React from 'react' | ||
import * as PropTypes from 'prop-types' | ||
|
||
import { | ||
ChildrenComponentProps, | ||
ContentComponentProps, | ||
createShorthandFactory, | ||
UIComponentProps, | ||
UIComponent, | ||
childrenExist, | ||
commonPropTypes, | ||
isFromKeyboard, | ||
} from '../../lib' | ||
|
||
import { ComponentEventHandler, WithAsProp, withSafeTypeForAs } from '../../types' | ||
import { Accessibility } from '../../lib/accessibility/types' | ||
import { defaultBehavior } from '../../lib/accessibility' | ||
import { IS_FOCUSABLE_ATTRIBUTE } from '../../lib/accessibility/FocusZone' | ||
import * as _ from 'lodash' | ||
|
||
export interface ToolbarCustomItemProps | ||
extends UIComponentProps, | ||
ChildrenComponentProps, | ||
ContentComponentProps { | ||
/** | ||
* Accessibility behavior if overridden by the user. | ||
*/ | ||
accessibility?: Accessibility | ||
|
||
/** A custom item can remove element padding, vertically or horizontally. */ | ||
fitted?: boolean | 'horizontally' | 'vertically' | ||
|
||
/** A custom item can be focused. */ | ||
focusable?: boolean | ||
|
||
/** A custom item can't be actionable. */ | ||
onClick: never | ||
|
||
/** | ||
* Called after user's focus. Will be called only if the item is focusable. | ||
* @param {SyntheticEvent} event - React's original SyntheticEvent. | ||
* @param {object} data - All props. | ||
*/ | ||
onFocus?: ComponentEventHandler<ToolbarCustomItemProps> | ||
|
||
/** | ||
* Called after item blur. Will be called only if the item is focusable. | ||
* @param {SyntheticEvent} event - React's original SyntheticEvent. | ||
* @param {object} data - All props. | ||
*/ | ||
onBlur?: ComponentEventHandler<ToolbarCustomItemProps> | ||
} | ||
|
||
interface ToolbarCustomItemState { | ||
isFromKeyboard: boolean | ||
} | ||
|
||
class ToolbarCustomItem extends UIComponent< | ||
WithAsProp<ToolbarCustomItemProps>, | ||
ToolbarCustomItemState | ||
> { | ||
static displayName = 'ToolbarCustomItem' | ||
|
||
static className = 'ui-toolbar__customitem' | ||
|
||
static create: Function | ||
|
||
static propTypes = { | ||
...commonPropTypes.createCommon(), | ||
fitted: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['horizontally', 'vertically'])]), | ||
focusable: PropTypes.bool, | ||
onFocus: PropTypes.func, | ||
onBlur: PropTypes.func, | ||
} | ||
|
||
static defaultProps = { | ||
accessibility: defaultBehavior, | ||
} | ||
|
||
handleBlur = (e: React.SyntheticEvent) => { | ||
if (this.props.focusable) { | ||
this.setState({ isFromKeyboard: false }) | ||
_.invoke(this.props, 'onBlur', e, this.props) | ||
} | ||
} | ||
|
||
handleFocus = (e: React.SyntheticEvent) => { | ||
if (this.props.focusable) { | ||
this.setState({ isFromKeyboard: isFromKeyboard() }) | ||
_.invoke(this.props, 'onFocus', e, this.props) | ||
} | ||
} | ||
|
||
renderComponent({ ElementType, classes, variables, accessibility, unhandledProps }) { | ||
const { children, content, focusable } = this.props | ||
return ( | ||
<ElementType | ||
{...accessibility.attributes.root} | ||
{...{ [IS_FOCUSABLE_ATTRIBUTE]: focusable }} | ||
{...unhandledProps} | ||
className={classes.root} | ||
onBlur={this.handleBlur} | ||
onFocus={this.handleFocus} | ||
> | ||
{childrenExist(children) ? children : content} | ||
</ElementType> | ||
) | ||
} | ||
} | ||
|
||
ToolbarCustomItem.create = createShorthandFactory({ | ||
Component: ToolbarCustomItem, | ||
mappedProp: 'content', | ||
}) | ||
|
||
/** | ||
* Custom toolbar item. | ||
* The item renders as a non-focusable div with custom content inside. | ||
*/ | ||
export default withSafeTypeForAs<typeof ToolbarCustomItem, ToolbarCustomItemProps>( | ||
ToolbarCustomItem, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
packages/react/src/themes/teams/components/Toolbar/toolbarCustomItemStyles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { ComponentSlotStylesInput, ICSSInJSStyle } from '../../../types' | ||
import { ToolbarCustomItemProps } from '../../../../components/Toolbar/ToolbarCustomItem' | ||
import { ToolbarVariables } from './toolbarVariables' | ||
import { getColorScheme } from '../../colors' | ||
|
||
const toolbarCustomItemStyles: ComponentSlotStylesInput< | ||
ToolbarCustomItemProps, | ||
ToolbarVariables | ||
> = { | ||
root: ({ props: p, variables: v }): ICSSInJSStyle => { | ||
const colors = getColorScheme(v.colorScheme) | ||
|
||
return { | ||
backgroundColor: v.background, | ||
borderColor: 'transparent', | ||
borderWidth: v.borderWidth, | ||
borderStyle: 'solid', | ||
height: v.itemHeight, | ||
color: v.foreground || colors.foreground1, | ||
display: 'flex', | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
...(p.fitted !== true && | ||
p.fitted !== 'horizontally' && { | ||
paddingLeft: v.customItemHorizontalPadding, | ||
paddingRight: v.customItemHorizontalPadding, | ||
}), | ||
...(p.fitted !== true && | ||
p.fitted !== 'vertically' && { | ||
paddingTop: v.customItemVerticalPadding, | ||
paddingBottom: v.customItemVerticalPadding, | ||
}), | ||
|
||
':focus': { | ||
outline: 0, | ||
}, | ||
|
||
...(p.isFromKeyboard && { | ||
color: v.foregroundFocus || colors.foregroundFocus, | ||
backgroundColor: v.backgroundFocus || colors.backgroundFocus, | ||
borderColor: v.borderFocus || colors.borderFocus, | ||
}), | ||
} | ||
}, | ||
} | ||
|
||
export default toolbarCustomItemStyles |
3 changes: 3 additions & 0 deletions
3
packages/react/src/themes/teams/components/Toolbar/toolbarCustomItemVariables.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import toolbarVariables from './toolbarVariables' | ||
|
||
export default toolbarVariables |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
packages/react/test/specs/components/Toolbar/ToolbarCustomItem-test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { isConformant } from 'test/specs/commonTests' | ||
|
||
import ToolbarCustomItem from 'src/components/Toolbar/ToolbarCustomItem' | ||
|
||
describe('ToolbarCustomItem', () => { | ||
isConformant(ToolbarCustomItem, { | ||
requiredProps: { focusable: true }, | ||
}) | ||
}) |