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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased]

### Features
- Add `Toolbar` component @miroslavstastny ([#1408](https://github.com/stardust-ui/react/pull/1408))

<!--------------------------------[ v0.32.0 ]------------------------------- -->
## [v0.32.0](https://github.com/stardust-ui/react/tree/v0.32.0) (2019-06-03)
[Compare changes](https://github.com/stardust-ui/react/compare/v0.31.0...v0.32.0)
Expand Down
1 change: 0 additions & 1 deletion docs/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ class App extends React.Component<any, ThemeContextData> {
<Provider
as={React.Fragment}
theme={mergeThemes(themes.fontAwesome, themes[themeName], {
// adjust Teams' theme to Semantic UI's font size scheme
staticStyles: [
{
a: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const config: ScreenerTestsConfig = { themes: ['teams', 'teamsDark', 'teamsHighContrast'] }

export default config
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import * as React from 'react'
import { Toolbar } from '@stardust-ui/react'

const ToolbarExampleShorthand = () => {
const [isBold, setBold] = React.useState(true)
const [isItalic, setItalic] = React.useState(false)
const [isUnderline, setUnderline] = React.useState(false)
const [isStrike, setStrike] = React.useState(false)

return (
<Toolbar
items={[
{
key: 'bold',
active: isBold,
icon: { name: 'bold', outline: true },
onClick: () => {
setBold(!isBold)
},
},
{
key: 'italic',
active: isItalic,
icon: { name: 'italic', outline: true },
onClick: () => {
setItalic(!isItalic)
},
},
{
key: 'underline',
active: isUnderline,
icon: { name: 'underline', outline: true },
onClick: () => {
setUnderline(!isUnderline)
},
},
{
key: 'strike',
active: isStrike,
disabled: true,
icon: { name: 'strike', outline: true },
onClick: () => {
setStrike(!isStrike)
},
},
{ key: 'divider1', kind: 'divider' },
{ key: 'highlight', icon: { name: 'highlight', outline: true } },
{ key: 'font-color', icon: { name: 'font-color', outline: true } },
{ key: 'font-size', icon: { name: 'font-size', outline: true } },
{ key: 'remove-format', icon: { name: 'remove-format', outline: true } },
{ key: 'divider2', kind: 'divider' },
{ key: 'outdent', icon: { name: 'outdent', outline: true } },
{ key: 'indent', icon: { name: 'indent', outline: true } },
{ key: 'bullets', icon: { name: 'bullets', outline: true } },
{ key: 'number-list', icon: { name: 'number-list', outline: true } },
{ key: 'divider3', kind: 'divider' },
{ key: 'more', icon: { name: 'more', outline: true } },
]}
/>
)
}

export default ToolbarExampleShorthand
15 changes: 15 additions & 0 deletions docs/src/examples/components/Toolbar/Types/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as React from 'react'
import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'

const Types = () => (
<ExampleSection title="Types">
<ComponentExample
title="Text editor toolbar"
description="A Toolbar use case for a text editor."
examplePath="components/Toolbar/Types/ToolbarExampleEditor"
/>
</ExampleSection>
)

export default Types
11 changes: 11 additions & 0 deletions docs/src/examples/components/Toolbar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react'

import Types from './Types'

const ToolbarExamples = () => (
<>
<Types />
</>
)

export default ToolbarExamples
11 changes: 9 additions & 2 deletions packages/react/src/components/Menu/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ export interface MenuItemProps
itemsCount?: number

/**
* Called on click. When passed, the component will render as an `a`
* tag by default instead of a `div`.
* Called on click.
*
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All props.
Expand All @@ -87,6 +86,13 @@ export interface MenuItemProps
*/
onFocus?: ComponentEventHandler<MenuItemProps>

/**
* Called after item blur.
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All props.
*/
onBlur?: ComponentEventHandler<MenuItemProps>

/** A menu can adjust its appearance to de-emphasize its contents. */
pills?: boolean

Expand Down Expand Up @@ -165,6 +171,7 @@ class MenuItem extends AutoControlledComponent<WithAsProp<MenuItemProps>, MenuIt
itemsCount: PropTypes.number,
onClick: PropTypes.func,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
pills: PropTypes.bool,
pointing: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['start', 'end'])]),
primary: customPropTypes.every([customPropTypes.disallow(['secondary']), PropTypes.bool]),
Expand Down
105 changes: 105 additions & 0 deletions packages/react/src/components/Toolbar/Toolbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import * as React from 'react'
import * as _ from 'lodash'
import * as customPropTypes from '@stardust-ui/react-proptypes'

import {
childrenExist,
createShorthandFactory,
UIComponent,
UIComponentProps,
ContentComponentProps,
ChildrenComponentProps,
commonPropTypes,
ColorComponentProps,
} from '../../lib'
import { Accessibility } from '../../lib/accessibility/types'
import { defaultBehavior } from '../../lib/accessibility'
import { ShorthandCollection, WithAsProp, withSafeTypeForAs } from '../../types'

import ToolbarItem from './ToolbarItem'
import ToolbarDivider from './ToolbarDivider'
import ToolbarRadioGroup from './ToolbarRadioGroup'

export type ToolbarItemShorthandKinds = 'divider' | 'item' | 'group'

export interface ToolbarProps
extends UIComponentProps,
ContentComponentProps,
ChildrenComponentProps,
ColorComponentProps {
/**
* Accessibility behavior if overridden by the user.
* @default defaultBehavior
*/
accessibility?: Accessibility

/** Shorthand array of props for Toolbar. */
items?: ShorthandCollection<ToolbarItemShorthandKinds>
}

class Toolbar extends UIComponent<WithAsProp<ToolbarProps>, any> {
static create: Function

static className = 'ui-toolbar'

static displayName = 'Toolbar'

static propTypes = {
...commonPropTypes.createCommon(),
items: customPropTypes.collectionShorthandWithKindProp(['divider', 'item', 'group']),
}

static defaultProps = {
accessibility: defaultBehavior,
}

static Item = ToolbarItem
static Divider = ToolbarDivider
static RadioGroup = ToolbarRadioGroup

handleItemOverrides = variables => predefinedProps => ({
variables: {
...variables,
...predefinedProps.variables,
},
})

private renderItems(items, variables) {
const itemOverridesFn = this.handleItemOverrides(variables)
return _.map(items, (item, index) => {
const kind = _.get(item, 'kind', 'item')

switch (kind) {
case 'divider':
return ToolbarDivider.create(item, { overrideProps: itemOverridesFn })
case 'group':
return ToolbarRadioGroup.create(item, { overrideProps: itemOverridesFn })
default:
return ToolbarItem.create(item, { overrideProps: itemOverridesFn })
}
})
}

renderComponent({
accessibility,
ElementType,
classes,
variables,
unhandledProps,
}): React.ReactNode {
const { children, items } = this.props

return (
<ElementType className={classes.root} {...accessibility.attributes.root} {...unhandledProps}>
{childrenExist(children) ? children : this.renderItems(items, variables)}
</ElementType>
)
}
}

Toolbar.create = createShorthandFactory({ Component: Toolbar, mappedProp: 'content' })

/**
* A Toolbar component displays grouped actions.
*/
export default withSafeTypeForAs<typeof Toolbar, ToolbarProps>(Toolbar)
57 changes: 57 additions & 0 deletions packages/react/src/components/Toolbar/ToolbarDivider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import * as React from 'react'
import {
ChildrenComponentProps,
ContentComponentProps,
createShorthandFactory,
UIComponentProps,
UIComponent,
commonPropTypes,
} from '../../lib'
import { Accessibility } from '../../lib/accessibility/types'
import { WithAsProp, withSafeTypeForAs } from '../../types'
import { defaultBehavior } from '../../lib/accessibility'

export interface ToolbarDividerProps
extends UIComponentProps,
ChildrenComponentProps,
ContentComponentProps {
/**
* Accessibility behavior if overridden by the user.
* @default defaultBehavior
*/
accessibility?: Accessibility
}

class ToolbarDivider extends UIComponent<WithAsProp<ToolbarDividerProps>> {
static displayName = 'ToolbarDivider'

static create: Function

static className = 'ui-toolbar__divider'

static propTypes = {
...commonPropTypes.createCommon(),
}

static defaultProps = {
accessibility: defaultBehavior as Accessibility,
}

renderComponent({ ElementType, classes, unhandledProps, accessibility }) {
return (
<ElementType
{...accessibility.attributes.root}
{...unhandledProps}
className={classes.root}
/>
)
}
}

ToolbarDivider.create = createShorthandFactory({ Component: ToolbarDivider, mappedProp: 'content' })

/**
* Toolbar divider.
* Adds visual non-selectable separator between items.
*/
export default withSafeTypeForAs<typeof ToolbarDivider, ToolbarDividerProps>(ToolbarDivider)
Loading