Skip to content

Commit

Permalink
[all] Replace sticky popover with popper.js based (#639)
Browse files Browse the repository at this point in the history
* [base] Overflow overlay is deprecated

* [all] Misc. cleanup and fixes

* [test-studio] Adding popover test

* [form-builder] Array css cleanup

* [components] Searchable select with popper

* [form-builder] Array ItemValue cleanup

* [components] EditItem with popperjs

* [all] Removing portal and sticky components.  Using general popover

* [components] Popover accepts popperjs modifiers

* [form-builder] Using popover on inline/span

* [components] Remove scrollcontainer-styles from selectmenu

* [form-builder] ActivateOnFocus contains toolbar too

* [components] Support for color danger

* [components] Cleanup story

* [form-builder] Only click outside on confirm button

* [components] Updating Snackbar to latest portal

* [components] Pure SearchableSelect component

* [components] Make popper handle all position and dimensions

* [form-builder] Hack to prevent events from making their way through portals

* [test-studio] Make recursive popover type actually recursive

* [components] Remove transform, with comment why for remember later

* [components] Cleanup popover nesting. Fixes react15 breakage

* [components] Replace react-portal dependency with stripped down and fixed version + cleanup

* [components] Using portal on dropdownbutton

* [form-builder] Allow specifying tagName for StopPropagation

* [base] Keep lightScrollbars

* [components] Remove redudant isOpen check

* [form-builder] Spesific events on popover. onClose, onEscape and onClickOutside

* [components] Rendering dropdown portal only when open

* [components] DropdownButton with portal z-index

* [components] PureComponent
  • Loading branch information
Kristoffer J. Sivertsen authored and bjoerge committed Mar 15, 2018
1 parent 1159237 commit f681449
Show file tree
Hide file tree
Showing 48 changed files with 848 additions and 1,802 deletions.
32 changes: 14 additions & 18 deletions packages/@sanity/base/src/styles/layout/scrolling.css
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
@import 'part:@sanity/base/theme/variables-style';

:root {
--defaultScrollBarWidth: var(--small-padding);
--defaultScrollBarWidth: calc(var(--small-padding) / 2);
}

.lightScrollbars {
@media (--screen-medium) {
@nest &::-webkit-scrollbar {
background-color: transparent;
width: var(--defaultScrollBarWidth);

@media (--screen-medium) {
width: var(--defaultScrollBarWidth);

@nest &:not(:hover) {
width: 0;
}
}
}

@nest &::-webkit-scrollbar * {
Expand All @@ -30,19 +22,18 @@
@nest &:hover {
@nest &::-webkit-scrollbar {
width: var(--defaultScrollBarWidth);
display: initial;

@media (--screen-medium) {
width: var(--defaultScrollBarWidth);
}
}

@nest &::-webkit-scrollbar-thumb {
background-color: var(--gray);
border-radius: calc(var(--defaultScrollBarWidth) / 2);
border: 2px color(var(--black) a(2%)) solid;
}

@nest &::-webkit-scrollbar-track {
background-color: color(var(--black) a(2%));
padding: 2px;
width: var(--defaultScrollBarWidth);
background-color: transparent;
}
}

Expand Down Expand Up @@ -78,23 +69,28 @@
}
}

.hideScrollbars {
-ms-overflow-style: -ms-autohiding-scrollbar;
overflow-style: overflow;
}

.touchScroll {
-webkit-overflow-scrolling: touch;
}

.scrollAll {
overflow: overlay;
overflow: auto;
composes: touchScroll;
}

.scrollX {
composes: touchScroll;
overflow-y: hidden;
overflow-x: overlay;
overflow-x: auto;
}

.scrollY {
composes: touchScroll;
overflow-y: overlay;
overflow-y: auto;
overflow-x: hidden;
}
7 changes: 4 additions & 3 deletions packages/@sanity/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"dialog-polyfill": "^0.4.3",
"dom-scroll-into-view": "^1.2.1",
"ease-component": "^1.0.0",
"element-resize-detector": "^1.1.10",
"element-resize-detector": "^1.1.14",
"exif-component": "^1.0.1",
"fuse.js": "^2.4.1",
"in-publish": "^2.0.0",
Expand All @@ -50,9 +50,9 @@
"react-dropzone": "^3.9.2",
"react-element-query": "^3.0.2",
"react-ink": "^6.1.0",
"react-portal": "^3.0.0",
"react-sortable-hoc": "^0.6.3",
"react-split-pane": "^0.1.63",
"react-popper": "^0.8.2",
"scroll": "^2.0.0"
},
"devDependencies": {
Expand All @@ -67,7 +67,8 @@
},
"peerDependencies": {
"prop-types": "^15.6 || ^16",
"react": "^15.6 || ^16"
"react": "^15.6 || ^16",
"react-dom": "^15.6 || ^16"
},
"repository": {
"type": "git",
Expand Down
37 changes: 8 additions & 29 deletions packages/@sanity/components/sanity.json
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@
"name": "part:@sanity/components/dialogs/popover",
"description": "Popover dialog. Points an arrow to parent element"
},
{
"name": "part:@sanity/components/dialogs/popover-style",
"description": "Popover styling"
},
{
"name": "part:@sanity/components/snackbar/default",
"description": "Shows messages with an action and a timeout."
Expand Down Expand Up @@ -310,10 +314,6 @@
"implements": "part:@sanity/components/drag-handle-style",
"path": "lists/styles/DragHandle.css"
},
{
"name": "part:@sanity/components/edititem/popover",
"description": "Edit item. Popover that points to the element"
},
{
"name": "part:@sanity/components/edititem/fold",
"description": "Edit item. Folds out and wraps around nearest relative container horizontally."
Expand Down Expand Up @@ -531,6 +531,10 @@
"implements": "part:@sanity/components/dialogs/popover",
"path": "dialogs/PopOver.js"
},
{
"implements": "part:@sanity/components/dialogs/popover-style",
"path": "dialogs/styles/PopOver.css"
},
{
"implements": "part:@sanity/components/fieldsets/default",
"path": "fieldsets/DefaultFieldset.js"
Expand All @@ -539,10 +543,6 @@
"implements": "part:@sanity/components/snackbar/default",
"path": "snackbar/DefaultSnackbar.js"
},
{
"implements": "part:@sanity/components/edititem/popover",
"path": "edititem/EditItemPopOver.js"
},
{
"implements": "part:@sanity/components/edititem/fold",
"path": "edititem/EditItemFoldOut.js"
Expand Down Expand Up @@ -723,10 +723,6 @@
"implements": "part:@sanity/components/lists/sortable-grid",
"path": "lists/sortable-grid"
},
{
"implements": "part:@sanity/components/edititem/popover-style",
"path": "edititem/styles/EditItemPopOver.css"
},
{
"implements": "part:@sanity/components/edititem/fold-style",
"path": "edititem/styles/EditItemFoldOut.css"
Expand Down Expand Up @@ -808,18 +804,6 @@
"implements": "part:@sanity/components/panes/split-pane-wrapper",
"path": "panes/SplitPaneWrapper.js"
},
{
"name": "part:@sanity/components/portal/sticky",
"description": "Portal that sticks to scrollContainer"
},
{
"implements": "part:@sanity/components/portal/sticky",
"path": "portal/Sticky.js"
},
{
"name": "part:@sanity/components/utilities/scroll-container",
"description": "Portal that sticks to scrollContainer"
},
{
"implements": "part:@sanity/components/utilities/scroll-container",
"path": "utilities/ScrollContainer.js"
Expand Down Expand Up @@ -923,11 +907,6 @@
{
"implements": "part:@sanity/base/component",
"path": "panes/story.js"
},
{
"implements": "part:@sanity/base/component",
"path": "portal/story.js"
}

]
}
116 changes: 36 additions & 80 deletions packages/@sanity/components/src/buttons/DropDownButton.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
/* eslint-disable complexity */
import PropTypes from 'prop-types'
import React from 'react'
import styles from 'part:@sanity/components/buttons/dropdown-style'
import Button from 'part:@sanity/components/buttons/default'
import ArrowIcon from 'part:@sanity/base/angle-down-icon'
import Menu from 'part:@sanity/components/menus/default'
import {omit} from 'lodash'
import StickyPortal from 'part:@sanity/components/portal/sticky'
import {Portal} from '../utilities/Portal'
import Stacked from '../utilities/Stacked'
import Escapable from '../utilities/Escapable'
import {Manager, Target, Popper} from 'react-popper'

class DropDownButton extends React.PureComponent {
export default class DropDownButton extends React.PureComponent {
static propTypes = {
kind: PropTypes.oneOf(['secondary', 'add', 'delete', 'warning', 'success', 'danger', 'simple']),
items: PropTypes.arrayOf(
Expand All @@ -35,16 +37,11 @@ class DropDownButton extends React.PureComponent {
}

state = {
menuOpened: false,
stickToBottom: true
menuOpened: false
}

width = 100

handleClickOutside = event => {
this.setState({menuOpened: false})
}

handleClose = () => {
this.setState({menuOpened: false})
}
Expand Down Expand Up @@ -72,98 +69,57 @@ class DropDownButton extends React.PureComponent {
this.handleClose()
}

handleResize = dimensions => {
const buttonHeight = this._rootElement.offsetHeight
if (this._menuElement.offsetHeight + buttonHeight < (window.innerHeight - dimensions.rootTop)) {
this.setState({
stickToBottom: true
})
return
}
this.setState({
stickToBottom: false
})
}

render() {
const {items, children, kind, className, origin, ...rest} = omit(this.props, 'onAction')
const {menuOpened, width, stickToBottom} = this.state


let menuClassName = styles.menu

if (stickToBottom && origin === 'right') {
menuClassName = styles.menuBottomRight
}

if (!stickToBottom && origin === 'right') {
menuClassName = styles.menuTopRight
}

if (stickToBottom && origin === 'left') {
menuClassName = styles.menuBottomLeft
}

if (!stickToBottom && origin === 'left') {
menuClassName = styles.menuTopLeft
}
const {menuOpened, width} = this.state

return (
<div ref={this.setRootElement} className={className}>
<Button
{...rest}
className={`${styles.root}`}
onClick={this.handleOnClick}
kind={kind}
>
<span className={styles.title}>
{children}
</span>

<span className={styles.arrow}>
<ArrowIcon color="inherit" />
</span>
<span
className={`
${stickToBottom ? styles.stickyBottom : styles.stickyTop}
${origin === 'left' ? styles.stickyLeft : styles.stickyRight}
`}
>
{
menuOpened && (
<Manager>
<Target>
<Button
{...rest}
className={`${styles.root}`}
onClick={this.handleOnClick}
kind={kind}
>
<span className={styles.title}>
{children}
</span>

<span className={styles.arrow}>
<ArrowIcon color="inherit" />
</span>
</Button>
</Target>
{
menuOpened && (
<Portal>
<Stacked>
{isActive => (
<StickyPortal
isOpen
onResize={this.handleResize}
onlyBottomSpace={false}
useOverlay={false}
addPadding={false}
scrollIntoView={false}
>
<Popper className={styles.popper}>
<div
className={styles.wrapper}
ref={this.setMenuElement}
style={{minWidth: `${width}px`}}
>
<Escapable onEscape={event => (isActive && this.handleClose())} />
<Escapable onEscape={isActive && this.handleClose} />
<Menu
items={items}
isOpen
className={menuClassName}
className={styles.menu}
onAction={this.handleAction}
onClickOutside={event => (isActive && this.handleClose())}
onClickOutside={isActive && this.handleClose}
/>
</div>
</StickyPortal>
</Popper>
)}
</Stacked>
)
}
</span>
</Button>
</Portal>
)
}
</Manager>
</div>
)
}
}

export default DropDownButton

0 comments on commit f681449

Please sign in to comment.