Skip to content

Commit

Permalink
feat(Responsive): add component (#1872)
Browse files Browse the repository at this point in the history
* feat(Breakpoint): add component

* feat(Breakpoint): add component

* feat(Breakpoint): add component

* style(Breakpoint): prefix bools with "is"

* refactor(Breakpoint): rename Responsive

* style(mixed): fix lint issues

* feat(Responsive): refactor component

* revert(customPropTypes): reverned unnecessary changes
  • Loading branch information
layershifter authored and levithomason committed Sep 11, 2017
1 parent 1fa93b2 commit 3a39d64
Show file tree
Hide file tree
Showing 19 changed files with 493 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, { Component } from 'react'
import { Responsive, Button, Menu } from 'semantic-ui-react'

export default class ResponsiveExampleContent extends Component {
state = { active: 'home' }

handleItemClick = (e, { name }) => this.setState({ active: name })

render() {
const { active } = this.state

return (
<Menu>
<Menu.Item active={active === 'home'} content='Home' name='home' onClick={this.handleItemClick} />
<Menu.Item active={active === 'messages'} content='Messages' name='messages' onClick={this.handleItemClick} />

<Menu.Menu position='right'>
<Menu.Item>
<Responsive
{...Responsive.onlyMobile}
as={Button}
content='Switch to desktop version'
icon='desktop'
labelPosition='left'
/>
<Responsive
as={Button}
content='Switch to mobile version'
icon='mobile'
labelPosition='left'
minWidth={Responsive.onlyTablet.minWidth}
/>
</Menu.Item>
</Menu.Menu>
</Menu>
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'
import { Responsive, Segment } from 'semantic-ui-react'

const ResponsiveExampleMaxWidth = () => (
<Segment.Group>
<Responsive as={Segment} maxWidth={767}>
Visible only if display has <code>767px</code> width and lower
</Responsive>
<Responsive as={Segment} maxWidth={2569}>
Visible only if display has <code>2569px</code> width
</Responsive>
</Segment.Group>
)

export default ResponsiveExampleMaxWidth
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'
import { Responsive, Segment } from 'semantic-ui-react'

const ResponsiveExampleMinWidth = () => (
<Segment.Group>
<Responsive as={Segment} minWidth={768}>
Visible only if display has <code>768px</code> width and higher
</Responsive>
<Responsive as={Segment} minWidth={992}>
Visible only if display has <code>992px</code> width and higher
</Responsive>
</Segment.Group>
)

export default ResponsiveExampleMinWidth
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import { Responsive, Segment } from 'semantic-ui-react'

const ResponsiveExampleMixed = () => (
<Responsive as={Segment} minWidth={320} maxWidth={2559}>
Visible only if display has width between <code>320px</code> and <code>2559px</code>
</Responsive>
)

export default ResponsiveExampleMixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import { Responsive, Segment } from 'semantic-ui-react'

const ResponsiveExampleResponsive = () => (
<Segment.Group>
<Responsive as={Segment}>I'm always visible by default</Responsive>
</Segment.Group>
)

export default ResponsiveExampleResponsive
41 changes: 41 additions & 0 deletions docs/app/Examples/addons/Responsive/Types/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react'
import { Message } from 'semantic-ui-react'

import ComponentExample from 'docs/app/Components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/app/Components/ComponentDoc/ExampleSection'

const ResponsiveTypesExamples = () => (
<ExampleSection title='Types'>
<ComponentExample
title='Responsive'
description='Responsive is always visible.'
examplePath='addons/Responsive/Types/ResponsiveExampleResponsive'
>
<Message info>
Instead of <code>Grid</code> visibility breakpoints, <code>Responsive</code> doesn't render invisible content.
</Message>
</ComponentExample>
<ComponentExample
title='Minimal Width'
description='You can pass minimal width value at which content will be displayed.'
examplePath='addons/Responsive/Types/ResponsiveExampleMinWidth'
/>
<ComponentExample
title='Maximum Width'
description='You can pass maximum width value at which content will be displayed.'
examplePath='addons/Responsive/Types/ResponsiveExampleMaxWidth'
/>
<ComponentExample
title='Mixed'
description='You can pass minimal and maximum width value at which content will be displayed.'
examplePath='addons/Responsive/Types/ResponsiveExampleMixed'
/>
<ComponentExample
title='Content'
description='Responsive can contain different content.'
examplePath='addons/Responsive/Types/ResponsiveExampleContent'
/>
</ExampleSection>
)

export default ResponsiveTypesExamples
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react'
import { Responsive, Segment } from 'semantic-ui-react'

const ResponsiveExampleBreakpoints = () => (
<Segment.Group>
<Responsive as={Segment} {...Responsive.onlyMobile}>Mobile</Responsive>
<Responsive as={Segment} {...Responsive.onlyTablet}>Tablet</Responsive>
<Responsive as={Segment} {...Responsive.onlyComputer}>Computer</Responsive>
<Responsive as={Segment} {...Responsive.onlyLargeScreen}>Large Screen</Responsive>
<Responsive as={Segment} {...Responsive.onlyWidescreen}>Widescreen</Responsive>
</Segment.Group>
)

export default ResponsiveExampleBreakpoints
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React, { Component } from 'react'
import { Button, Grid, Label, Responsive, Segment } from 'semantic-ui-react'

export default class ResponsiveExampleOnUpdate extends Component {
state = {
log: [],
logCount: 0,
}

handleOnUpdate = () => this.setState({
log: [
`${new Date().toLocaleTimeString()}: onUpdate()`,
...this.state.log,
].slice(0, 20),
logCount: this.state.logCount + 1,
})

clearLog = () => this.setState({ log: [], logCount: 0 })

render() {
const { log, logCount } = this.state

return (
<Grid columns={2}>
<Grid.Column>
<Responsive as={Segment} onUpdate={this.handleOnUpdate}>
Responsive Segment
</Responsive>
</Grid.Column>

<Grid.Column>
<Segment.Group>
<Segment>
<Button
compact
content='Clear'
floated='right'
onClick={this.clearLog}
size='small'
/>
Event Log <Label circular>{logCount}</Label>
</Segment>
{log.length > 0 && (
<Segment secondary>
<pre>{log.map((e, i) => <div key={i}>{e}</div>)}</pre>
</Segment>
)}
</Segment.Group>
</Grid.Column>
</Grid>
)
}
}
21 changes: 21 additions & 0 deletions docs/app/Examples/addons/Responsive/Usage/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'

import ComponentExample from 'docs/app/Components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/app/Components/ComponentDoc/ExampleSection'

const ResponsiveUsageExamples = () => (
<ExampleSection title='Usage'>
<ComponentExample
title='Predefined breakpoints'
description='Responsive has predefined breakpoints that mimics SUI default variables.'
examplePath='addons/Responsive/Usage/ResponsiveExampleBreakpoints'
/>
<ComponentExample
title='OnUpdate'
description='Responsive listens for window resize events and calls event handler.'
examplePath='addons/Responsive/Usage/ResponsiveExampleOnUpdate'
/>
</ExampleSection>
)

export default ResponsiveUsageExamples
13 changes: 13 additions & 0 deletions docs/app/Examples/addons/Responsive/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react'

import Types from './Types'
import Usage from './Usage'

const ResponsiveExamples = () => (
<div>
<Types />
<Usage />
</div>
)

export default ResponsiveExamples
5 changes: 5 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
// Addons
export {
default as Responsive,
ResponsiveProps,
ResponsiveWidthShorthand
} from './dist/commonjs/addons/Responsive';
export { default as Confirm, ConfirmProps } from './dist/commonjs/addons/Confirm';
export { default as Portal, PortalProps } from './dist/commonjs/addons/Portal';
export { default as Radio, RadioProps } from './dist/commonjs/addons/Radio';
Expand Down
44 changes: 44 additions & 0 deletions src/addons/Responsive/Responsive.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as React from 'react';

export interface ResponsiveProps {
[key: string]: any;

/** An element type to render as (string or function). */
as?: any;

/** Primary content. */
children?: React.ReactNode;

/** The maximum width at which content will be displayed. */
maxWidth?: number | string;

/** The minimum width at which content will be displayed. */
minWidth?: number | string;

/**
* Called on update.
*
* @param {SyntheticEvent} event - The React SyntheticEvent object
* @param {object} data - All props and the event value.
*/
onUpdate?: (event: React.SyntheticEvent<HTMLElement>, data: ResponsiveOnUpdateData) => void;
}

export interface ResponsiveOnUpdateData extends ResponsiveProps {
width: string;
}

export interface ResponsiveWidthShorthand {
minWidth: number;
maxWidth?: number;
}

declare class Responsive extends React.Component<ResponsiveProps, {}> {
static onlyMobile: ResponsiveWidthShorthand;
static onlyTablet: ResponsiveWidthShorthand;
static onlyComputer: ResponsiveWidthShorthand;
static onlyLargeScreen: ResponsiveWidthShorthand;
static onlyWidescreen: ResponsiveWidthShorthand;
}

export default Responsive;
Loading

0 comments on commit 3a39d64

Please sign in to comment.