Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Responsive): add component #1872

Merged
merged 14 commits into from
Sep 11, 2017
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
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