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

Commit

Permalink
feat(Popup): make 'content' prop to be a shorthand (#322)
Browse files Browse the repository at this point in the history
* introduce Popup content prop as a shorthand

* fix popup content shorthand factory for primitives

* introduce popup content example

* fix popup examples

* update changelog

* simplify popup content wrapper examples

* fix create factory of PopupContent
  • Loading branch information
kuzhelov authored Oct 8, 2018
1 parent 6878534 commit 763973a
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 26 deletions.
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
- Make `content` to be a shorthand prop for `Popup` @kuzhelov ([#322](https://github.com/stardust-ui/react/pull/322))

<!--------------------------------[ v0.9.0 ]------------------------------- -->
## [v0.9.0](https://github.com/stardust-ui/react/tree/v0.9.0) (2018-10-07)
[Compare changes](https://github.com/stardust-ui/react/compare/v0.8.0...v0.9.0)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react'
import { Button, Popup } from '@stardust-ui/react'

class PopupContentWrapperExample extends React.Component<any, any> {
state = {
firstPopupOpen: false,
secondPopupOpen: false,
}

render() {
const plainContentStyle = {
zIndex: 1000,
padding: 5,
}

return (
<>
<Popup
open={this.state.firstPopupOpen}
content={<p style={plainContentStyle}>Plain popup content rendered 'as is'.</p>}
trigger={
<Button
icon="expand"
onClick={() => this.setState(prev => ({ firstPopupOpen: !prev.firstPopupOpen }))}
content="Popup with plain content"
/>
}
/>

<Popup
open={this.state.secondPopupOpen}
content={{ content: <p style={plainContentStyle}>Popup content rendered in wrapper.</p> }}
trigger={
<Button
icon="expand"
onClick={() => this.setState(prev => ({ secondPopupOpen: !prev.secondPopupOpen }))}
content="Popup with wrapped content"
/>
}
/>
</>
)
}
}

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

class PopupContentWrapperExample extends React.Component<any, any> {
state = {
firstPopupOpen: false,
secondPopupOpen: false,
}

render() {
const plainContentStyle = {
zIndex: 1000,
padding: 5,
}

return (
<>
<Popup
open={this.state.firstPopupOpen}
content={<p style={plainContentStyle}>Plain popup content rendered 'as is'.</p>}
>
<Button
icon="expand"
onClick={() => this.setState(prev => ({ firstPopupOpen: !prev.firstPopupOpen }))}
content="Popup with plain content"
/>
</Popup>

<Popup
open={this.state.secondPopupOpen}
content={{ content: <p style={plainContentStyle}>Popup content rendered in wrapper.</p> }}
>
<Button
icon="expand"
onClick={() => this.setState(prev => ({ secondPopupOpen: !prev.secondPopupOpen }))}
content="Popup with wrapped content"
/>
</Popup>
</>
)
}
}

export default PopupContentWrapperExample
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class PopupControlledExample extends React.Component<any, any> {
this.setState({ popupOpen: newProps.open })
}}
trigger={<Button icon="expand" onClick={() => this.togglePopup()} />}
content={<Input icon="search" placeholder="Search..." />}
content={{ content: <Input icon="search" placeholder="Search..." /> }}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class PopupControlledExample extends React.Component<any, any> {
alert(`Popup is requested to change its open state to "${newProps.open}".`)
this.setState({ popupOpen: newProps.open })
}}
content={<Input icon="search" placeholder="Search..." />}
content={{ content: <Input icon="search" placeholder="Search..." /> }}
>
<Button icon="expand" onClick={() => this.togglePopup()} />
</Popup>
Expand Down
5 changes: 5 additions & 0 deletions docs/src/examples/components/Popup/Types/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ const Types = () => (
description="Note that if Popup is controlled, then its 'open' prop value could be changed either by parent component, or by user actions (e.g. key press) - thus it is necessary to handle 'onOpenChanged' event. Try to type some text into popup's input field and press ESC to see the effect."
examplePath="components/Popup/Types/PopupControlledExample"
/>
<ComponentExample
title="Content Wrapper"
description="Use 'content' prop of the Popup to set whether Popup content should be rendered with the default wrapper."
examplePath="components/Popup/Types/PopupContentWrapperExample"
/>
</ExampleSection>
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ class PopupWithButton extends React.Component<any, any> {
styles={{ padding, height: '38px', minWidth: '64px' }}
/>
}
content={
<p>
The popup is rendered {position} the trigger<br />aligned to the {align}.
</p>
}
content={{
content: (
<p>
The popup is rendered {position} the trigger<br />aligned to the {align}.
</p>
),
}}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ class PopupArrowExample extends React.Component<any, any> {
open={this.state.popupOpen}
align={align}
position={position}
content={
<p>
The popup is rendered {position} the trigger<br />aligned to the {align}.
</p>
}
content={{
content: (
<p>
The popup is rendered {position} the trigger<br />aligned to the {align}.
</p>
),
}}
>
<Button
onClick={() => this.togglePopupState()}
Expand Down
28 changes: 17 additions & 11 deletions src/components/Popup/Popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import * as PropTypes from 'prop-types'
import _ from 'lodash'
import { Popper, PopperChildrenProps } from 'react-popper'

import { childrenExist, AutoControlledComponent, IRenderResultConfig, isBrowser } from '../../lib'
import {
childrenExist,
customPropTypes,
AutoControlledComponent,
IRenderResultConfig,
isBrowser,
} from '../../lib'
import {
ComponentEventHandler,
ShorthandValue,
Expand Down Expand Up @@ -32,7 +38,7 @@ export interface IPopupProps {
align?: Alignment
children?: ReactChildren
className?: string
content?: ShorthandValue | ShorthandValue[]
content?: ShorthandValue
defaultOpen?: boolean
open?: boolean
onOpenChange?: ComponentEventHandler<IPopupProps>
Expand Down Expand Up @@ -74,7 +80,7 @@ export default class Popup extends AutoControlledComponent<Extendable<IPopupProp
className: PropTypes.string,

/** The popup content. */
content: PropTypes.any,
content: customPropTypes.itemShorthand,

/** Initial value for 'open'. */
defaultOpen: PropTypes.bool,
Expand Down Expand Up @@ -179,14 +185,14 @@ export default class Popup extends AutoControlledComponent<Extendable<IPopupProp

return (
<Ref innerRef={domElement => ref(domElement)}>
<Popup.Content
{...rtl && { dir: 'rtl' }}
style={popupPlacementStyles}
{...accessibility.attributes.popup}
{...accessibility.keyHandlers.popup}
>
{content}
</Popup.Content>
{Popup.Content.create(content, {
defaultProps: {
...(rtl && { dir: 'rtl' }),
style: popupPlacementStyles,
...accessibility.attributes.popup,
...accessibility.keyHandlers.popup,
},
})}
</Ref>
)
}
Expand Down
26 changes: 23 additions & 3 deletions src/components/Popup/PopupContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@ import * as _ from 'lodash'
import * as PropTypes from 'prop-types'
import * as React from 'react'

import { customPropTypes, UIComponent, IRenderResultConfig } from '../../lib'
import {
childrenExist,
createShorthandFactory,
customPropTypes,
UIComponent,
IRenderResultConfig,
} from '../../lib'
import { ComponentVariablesInput, ComponentPartStyle } from '../../../types/theme'
import { Extendable, ReactChildren } from '../../../types/utils'

export interface IPopupContentProps {
as?: any
children?: ReactChildren
content?: any
className?: string
styles?: ComponentPartStyle
variables?: ComponentVariablesInput
Expand All @@ -19,7 +26,9 @@ export interface IPopupContentProps {
* @accessibility This is example usage of the accessibility tag.
* This should be replaced with the actual description after the PR is merged
*/
export default class PopupContent extends UIComponent<Extendable<IPopupContentProps>, any> {
class PopupContent extends UIComponent<Extendable<IPopupContentProps>, any> {
public static create: Function

public static displayName = 'PopupContent'
public static className = 'ui-popup__content'

Expand All @@ -33,6 +42,11 @@ export default class PopupContent extends UIComponent<Extendable<IPopupContentPr
*/
children: PropTypes.node,

/**
* Wraped content.
*/
content: PropTypes.any,

/** Additional CSS class name(s) to apply. */
className: PropTypes.string,

Expand All @@ -48,10 +62,16 @@ export default class PopupContent extends UIComponent<Extendable<IPopupContentPr
classes,
rest,
}: IRenderResultConfig<IPopupContentProps>): React.ReactNode {
const { children, content } = this.props

return (
<ElementType className={classes.root} {...rest}>
{this.props.children}
{childrenExist(children) ? children : content}
</ElementType>
)
}
}

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

export default PopupContent

0 comments on commit 763973a

Please sign in to comment.