Skip to content

Commit

Permalink
feat: add spacing and rtl props
Browse files Browse the repository at this point in the history
  • Loading branch information
jedwards1211 committed Apr 17, 2019
1 parent 0567c8b commit fd3aa5b
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 8 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,31 @@ only render the active view.
The index of the view that should be showing. Whenever you change this, `ViewSlider` will animate a horizontal slide
transition to the view at the new index.

##### `spacing: number` (default: `1`)

How much horizontal space to put between the views. `spacing={1.5}` will space
the views apart by 50% of the width, `spacing={2}` will space the views apart
by 100% of the width, etc.

Views without much horizontal padding or margin of their own will look jammed
together during transitions with a default `spacing` of 1, so in that case
you'll want to increase the `spacing`.

A negative number will reverse the view order;
`spacing={-1.5}` will arrange views from right to left with 50% width view
spacing. You can also use the `rtl` property for this, especially if you want
the views to inherit `direction: rtl` for their own content layout.

##### `rtl: boolean` (default: false)

Whether to use right-to-left layout. This will reverse the view order and apply
`direction: rtl` to the viewport style, and each view will inherit that layout
direction for its own content as well.

To reverse the view order without
changing layout direction of each view's content, you can use a negative number
for `spacing`.

##### `keepViewsMounted: boolean` (default: `false`)

If `true`, `ViewSlider` will keep all views mounted after transitioning, not just the active view.
Expand Down
39 changes: 37 additions & 2 deletions demo/examples/SignupDemo.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import * as React from 'react'
import Link from '@material-ui/core/Link'
import Button from '@material-ui/core/Button'
import TextField from '@material-ui/core/TextField'
import Typography from '@material-ui/core/Typography'
Expand Down Expand Up @@ -81,7 +82,9 @@ const SignupDemo = ({ classes }: Props): React.Node => {
</Button>
<div className={classes.contentHolder}>
<Paper className={classes.paper}>
<ViewSlider animateHeight>{content}</ViewSlider>
<ViewSlider animateHeight spacing={1.2}>
{content}
</ViewSlider>
</Paper>
</div>
</div>
Expand Down Expand Up @@ -194,7 +197,39 @@ const PasswordForm = ({ classes, onSubmit }: FormProps): React.Node => {
const DoneForm = ({ classes, onSubmit }: FormProps): React.Node => (
<div className={classes.form}>
<Typography variant="h5" className={classes.h5}>
<em>End of Demo</em>
<em>Thank you</em> for viewing the demo!
</Typography>
<Typography variant="h6">Additional libraries to check out:</Typography>
<Typography variant="h5">
<Link href="https://github.com/jcoreio/react-router-drilldown">
<code>react-router-drilldown</code>
</Link>
</Typography>
<Typography variant="body1" component="p">
uses <code>react-view-slider</code> to animate transitions between routes
in <code>react-router</code>.
</Typography>
<Typography variant="h5">
<Link href="https://github.com/jcoreio/react-fader">
<code>react-fader</code>
</Link>
</Typography>
<Typography variant="body1" component="p">
component that fades out its old child, then fades in its new child when
its children change. It can also optionally animate its height and/or
width from one child{"'"}s size to the other. Also works well with{' '}
<code>react-router</code>!
</Typography>
<Typography variant="h5">
<Link href="https://github.com/jcoreio/react-transition-context">
<code>react-transition-context</code>
</Link>
</Typography>
<Typography variant="body1" component="p">
Allows you to perform effects when transitions in an ancestor component
start or end (used to automatically focus the inputs in this demo). Also
works with <code>react-router-drilldown</code> and{' '}
<code>react-fader</code>!
</Typography>
</div>
)
Expand Down
21 changes: 17 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export type DefaultProps = {
prefixer: Prefixer,
style: Object,
viewportStyle: Object,
rtl: boolean,
spacing: number,
}

export type Props = {
Expand All @@ -39,6 +41,8 @@ export type Props = {
viewportStyle: Object,
rootRef?: (node: ?React.ElementRef<'div'>) => mixed,
viewportRef?: (node: ?React.ElementRef<'div'>) => mixed,
rtl: boolean,
spacing: number,
}

export type State = {
Expand All @@ -57,7 +61,6 @@ const fillStyle = {
}

const viewStyle = {
position: 'relative',
display: 'inline-block',
verticalAlign: 'top',
whiteSpace: 'normal',
Expand All @@ -73,6 +76,8 @@ export default class ViewSlider extends React.Component<Props, State> {
prefixer: new Prefixer(),
style: {},
viewportStyle: {},
rtl: false,
spacing: 1,
}
state: State = {
height: undefined,
Expand Down Expand Up @@ -167,14 +172,18 @@ export default class ViewSlider extends React.Component<Props, State> {
}

renderView = (index: number): React.Node => {
const { fillParent, prefixer, keepViewsMounted } = this.props
const { fillParent, prefixer, keepViewsMounted, spacing, rtl } = this.props
const { activeView, transitioning } = this.state

const style: Object = { display: 'flex', ...viewStyle }
if (fillParent) {
Object.assign(style, fillStyle)
style.overflow = 'auto'
style.left = `${index * 100}%`
if (rtl) style.right = `${index * spacing * 100}%`
else style.left = `${index * spacing * 100}%`
} else if (index > 0) {
if (rtl) style.marginRight = `${(spacing - 1) * 100}%`
else style.marginLeft = `${(spacing - 1) * 100}%`
}

// when not transitioning, render empty placeholder divs before the active view to push it into the right
Expand Down Expand Up @@ -229,6 +238,8 @@ export default class ViewSlider extends React.Component<Props, State> {
transitionDuration,
transitionTimingFunction,
keepViewsMounted,
rtl,
spacing,
} = this.props
const animateHeight = this.animateHeight()
const { activeView, height, transitioning } = this.state
Expand All @@ -243,9 +254,11 @@ export default class ViewSlider extends React.Component<Props, State> {
}

const finalViewportStyle = {
transform: `translateX(-${activeView * 100}%)`,
position: 'relative',
transform: `translateX(${activeView * spacing * (rtl ? 100 : -100)}%)`,
whiteSpace: 'nowrap',
minHeight: '100%',
direction: rtl ? 'rtl' : 'ltr',
transition: transitioning
? `transform ${transitionTimingFunction} ${transitionDuration}ms`
: undefined,
Expand Down
9 changes: 7 additions & 2 deletions src/simple.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import * as React from 'react'
import Prefixer from 'inline-style-prefixer'
import ViewSlider from './index'

import type { Props as ViewSliderProps, ViewProps } from './index'

export type Props = {
Expand All @@ -21,6 +20,8 @@ export type Props = {
viewportStyle?: Object,
rootRef?: (node: ?React.ElementRef<'div'>) => mixed,
viewportRef?: (node: ?React.ElementRef<'div'>) => mixed,
rtl?: ?boolean,
spacing?: ?number,
}

export type State = {
Expand All @@ -37,7 +38,6 @@ export function createSimpleViewSlider(
renderView: (props: ViewProps) => React.Node = defaultRenderView
): Class<React.Component<Props, State>> {
return class SimpleViewSlider extends React.Component<Props, State> {
static defaultProps: Props
state: State

constructor(props: Props) {
Expand Down Expand Up @@ -70,12 +70,17 @@ export function createSimpleViewSlider(
render(): React.Node {
const {
children, // eslint-disable-line no-unused-vars
// Flow's React.ComponentType + defaultProps is foobar...
spacing,
rtl,
...props
} = this.props
const { activeView, views } = this.state
return (
<ViewSlider
{...props}
spacing={(spacing: any)}
rtl={(rtl: any)}
renderView={this.renderView}
numViews={views.length}
activeView={activeView}
Expand Down

0 comments on commit fd3aa5b

Please sign in to comment.