Skip to content
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
2 changes: 1 addition & 1 deletion src/autocomplete/src/Autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import fuzzaldrin from 'fuzzaldrin-plus'
import Downshift from 'downshift'
import VirtualList from 'react-tiny-virtual-list'
import { Popover } from '../../popover'
import { Position } from '../../positioner'
import { Position } from '../../constants'
import { Heading } from '../../typography'
import { Pane } from '../../layers'
import AutocompleteItem from './AutocompleteItem'
Expand Down
1 change: 1 addition & 0 deletions src/constants/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as StackingOrder } from './src/StackingOrder'
export { default as Intent } from './src/Intent'
export { default as Position } from './src/Position'
10 changes: 10 additions & 0 deletions src/constants/src/Position.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default {
TOP: 'top',
TOP_LEFT: 'top-left',
TOP_RIGHT: 'top-right',
BOTTOM: 'bottom',
BOTTOM_LEFT: 'bottom-left',
BOTTOM_RIGHT: 'bottom-right',
LEFT: 'left',
RIGHT: 'right'
}
4 changes: 2 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export { Badge, Pill } from './badges'
export { BackButton, Button, IconButton, TextDropdownButton } from './buttons'
export { Checkbox } from './checkbox'
export { Combobox } from './combobox'
export { StackingOrder, Intent } from './constants'
export { StackingOrder, Intent, Position } from './constants'
export { CornerDialog } from './corner-dialog'
export { Dialog } from './dialog'
export { FilePicker } from './file-picker'
Expand All @@ -27,7 +27,7 @@ export { Menu } from './menu'
export { Overlay } from './overlay'
export { Popover } from './popover'
export { Portal } from './portal'
export { Positioner, Position } from './positioner'
export { Positioner } from './positioner'
export { Radio, RadioGroup } from './radio'
export { minorScale, majorScale } from './scales'
export { SearchInput } from './search-input'
Expand Down
2 changes: 1 addition & 1 deletion src/menu/stories/index.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Menu from '../src/Menu'
import { Button } from '../../buttons'
import { UnorderedList, ListItem } from '../../typography'
import { Popover } from '../../popover'
import { Position } from '../../positioner'
import { Position } from '../../constants'

storiesOf('menu', module)
.add('dropdown', () => (
Expand Down
2 changes: 1 addition & 1 deletion src/popover/docs/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import Box from 'ui-box'
import Popover from '../src/Popover'
import { Position } from '../../positioner'
import { Position } from '../../constants'
import { Button } from '../../buttons'
import { Text } from '../../typography'
import { Pane } from '../../layers'
Expand Down
12 changes: 10 additions & 2 deletions src/popover/src/Popover.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Position, Positioner } from '../../positioner'
import { Positioner } from '../../positioner'
import { Tooltip } from '../../tooltip'
import { Position } from '../../constants'
import PopoverStateless from './PopoverStateless'

export default class Popover extends Component {
static propTypes = {
/**
* The position the Popover is on. Smart positioning might override this.
*/
position: PropTypes.oneOf(Object.keys(Position)),
position: PropTypes.oneOf([
Position.TOP,
Position.TOP_LEFT,
Position.TOP_RIGHT,
Position.BOTTOM,
Position.BOTTOM_LEFT,
Position.BOTTOM_RIGHT
]),

/**
* When true, the Popover is manually shown.
Expand Down
2 changes: 1 addition & 1 deletion src/popover/stories/index.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { TextInputField } from '../../text-input'
import { Pane } from '../../layers'
import { Heading, Paragraph, Text } from '../../typography'
import { Button } from '../../buttons'
import { Position } from '../../positioner'
import { Position } from '../../constants'
import { Icon, IconNames } from '../../icon'

const PopoverContent = () => (
Expand Down
3 changes: 1 addition & 2 deletions src/positioner/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { default as Positioner } from './src/Positioner'
export { default as Position } from './src/Position'
export { default as Positioner } from './src/Positioner' // eslint-disable-line import/prefer-default-export
8 changes: 0 additions & 8 deletions src/positioner/src/Position.js

This file was deleted.

12 changes: 9 additions & 3 deletions src/positioner/src/Positioner.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import PropTypes from 'prop-types'
import Transition from 'react-transition-group/Transition'
import { Portal } from '../../portal'
import { Stack } from '../../stack/'
import { StackingOrder } from '../../constants'
import { StackingOrder, Position } from '../../constants'
import getPosition from './getPosition'
import Position from './Position'

const animationEasing = {
spring: `cubic-bezier(0.175, 0.885, 0.320, 1.175)`
Expand Down Expand Up @@ -41,7 +40,14 @@ export default class Positioner extends PureComponent {
* The position the element that is being positioned is on.
* Smart positioning might override this.
*/
position: PropTypes.oneOf(Object.keys(Position)).isRequired,
position: PropTypes.oneOf([
Position.TOP,
Position.TOP_LEFT,
Position.TOP_RIGHT,
Position.BOTTOM,
Position.BOTTOM_LEFT,
Position.BOTTOM_RIGHT
]).isRequired,

/**
* When true, show the element being positioned.
Expand Down
2 changes: 1 addition & 1 deletion src/positioner/src/getPosition.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Position from './Position'
import { Position } from '../../constants'

/**
* Function to create a Rect.
Expand Down
11 changes: 9 additions & 2 deletions src/select-menu/src/SelectMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import arrify from 'arrify'
import { Popover } from '../../popover'
import { Position } from '../../positioner'
import { Position } from '../../constants'
import SelectMenuContent from './SelectMenuContent'
import OptionShapePropType from './OptionShapePropType'
import SelectedPropType from './SelectedPropType'
Expand Down Expand Up @@ -63,7 +63,14 @@ export default class SelectMenu extends PureComponent {
/**
* The position of the Select Menu.
*/
position: PropTypes.oneOf(Object.keys(Position)),
position: PropTypes.oneOf([
Position.TOP,
Position.TOP_LEFT,
Position.TOP_RIGHT,
Position.BOTTOM,
Position.BOTTOM_LEFT,
Position.BOTTOM_RIGHT
]),

/**
* Can be a function that returns a node, or a node itself, that is
Expand Down
150 changes: 109 additions & 41 deletions src/side-sheet/src/SheetClose.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
import Box from 'ui-box'
import { css } from 'glamor'
import { Icon } from '../../icon'
import { Position } from '../../constants'

const animationEasing = {
deceleration: `cubic-bezier(0.0, 0.0, 0.2, 1)`,
Expand All @@ -11,72 +12,139 @@ const animationEasing = {

const ANIMATION_DURATION = 240

const rotate360InAnimation = css.keyframes('rotate360InAnimation', {
from: {
transform: `translateX(100%) rotate(0deg)`
},
to: {
transform: `translateX(-100%) rotate(-360deg)`
}
})

const rotate360OutAnimation = css.keyframes('rotate360OutAnimation', {
from: {
transform: `translateX(-100%) rotate(0deg)`
},
to: {
transform: `translateX(100%) rotate(360deg)`
}
})

const sheetCloseClassName = css({
const sharedStyles = {
padding: 4,
borderRadius: 9999,
position: 'absolute',
cursor: 'pointer',
transform: `translateX(-100%)`,
backgroundColor: `rgba(255, 255, 255, 0.4)`,
transition: `background-color 120ms`,
'&:hover': {
backgroundColor: `rgba(255, 255, 255, 0.6)`
},
'&:active': {
backgroundColor: `rgba(255, 255, 255, 0.4)`
}
}

const withAnimations = (animateIn, animateOut) => {
return {
'&[data-state="entering"], &[data-state="entered"]': {
animation: `${animateIn} ${ANIMATION_DURATION}ms ${
animationEasing.deceleration
} both`
},
'&[data-state="exiting"]': {
animation: `${animateOut} ${ANIMATION_DURATION}ms ${
animationEasing.acceleration
} both`
}
}
}

const sheetCloseStyles = {
[Position.RIGHT]: {
left: 0,
marginLeft: -12,
marginTop: 12,
transform: `translateX(-100%)`,
...withAnimations(
css.keyframes('rotate360InAnimation', {
from: { transform: `translateX(100%) rotate(0deg)` },
to: { transform: `translateX(-100%) rotate(-360deg)` }
}),
css.keyframes('rotate360OutAnimation', {
from: { transform: `translateX(-100%) rotate(0deg)` },
to: { transform: `translateX(100%) rotate(360deg)` }
})
)
},
'&[data-state="entering"], &[data-state="entered"]': {
animation: `${rotate360InAnimation} ${ANIMATION_DURATION}ms ${
animationEasing.deceleration
} both`
[Position.LEFT]: {
marginRight: -12,
right: 0,
marginTop: 12,
transform: `translateX(100%)`,
...withAnimations(
css.keyframes('leftRotate360InAnimation', {
from: { transform: `translateX(-100%) rotate(0deg)` },
to: { transform: `translateX(100%), rotate(360deg)` }
}),
css.keyframes('leftRotate360OutAnimation', {
from: { transform: `translateX(100%) rotate(0deg)` },
to: { transform: `translateX(-100%), rotate(360deg)` }
})
)
},
[Position.TOP]: {
right: 0,
marginRight: 12,
top: '100%',
marginTop: 12,
transform: `translateY(0)`,
...withAnimations(
css.keyframes('topRotate360InAnimation', {
from: { transform: `translateY(-200%) rotate(0deg)` },
to: { transform: `translateY(0%), rotate(360deg)` }
}),
css.keyframes('topRotate360OutAnimation', {
from: { transform: `translateY(0%) rotate(0deg)` },
to: { transform: `translateY(-200%), rotate(360deg)` }
})
)
},
'&[data-state="exiting"]': {
animation: `${rotate360OutAnimation} ${ANIMATION_DURATION}ms ${
animationEasing.acceleration
} both`
[Position.BOTTOM]: {
right: 0,
marginRight: 12,
bottom: '100%',
marginBottom: 12,
transform: `translateY(0)`,
...withAnimations(
css.keyframes('bottomRotate360InAnimation', {
from: { transform: `translateY(200%) rotate(0deg)` },
to: { transform: `translateY(0%), rotate(360deg)` }
}),
css.keyframes('bottomRotate360OutAnimation', {
from: { transform: `translateY(0%) rotate(0deg)` },
to: { transform: `translateY(200%), rotate(360deg)` }
})
)
}
})
}

const sheetCloseClassNameCache = {}

const getSheetCloseClassName = position => {
if (!sheetCloseClassNameCache[position]) {
sheetCloseClassNameCache[position] = css({
...sheetCloseStyles[position],
...sharedStyles
}).toString()
}
return sheetCloseClassNameCache[position]
}

export default class SheetClose extends PureComponent {
static propTypes = {
...Box.propTypes,
isClosing: PropTypes.bool
}

static styles = {
position: 'absolute',
marginLeft: -12,
marginTop: 12,
padding: 4,
borderRadius: 9999
isClosing: PropTypes.bool,
position: PropTypes.oneOf([
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a default position? or else mark this as required?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should probably just mark it as required. The default value is effectively provided by the SideSheet component.

Position.LEFT,
Position.RIGHT,
Position.TOP,
Position.BOTTOM
]).isRequired
}

render() {
const { isClosing, ...props } = this.props
const { isClosing, position, ...props } = this.props
return (
<Box
width={32}
height={32}
display="flex"
alignItems="center"
justifyContent="center"
className={sheetCloseClassName.toString()}
{...SheetClose.styles}
className={getSheetCloseClassName(position)}
{...props}
>
<Icon icon="cross" color="#fff" />
Expand Down
Loading