react-dom#findDOMNode JavaScript Examples
The following examples show how to use
react-dom#findDOMNode.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.js From the-eye-knows-the-garbage with MIT License | 7 votes |
export function isEventFromHandle(e, handles) {
try {
return Object.keys(handles).some(function (key) {
return e.target === findDOMNode(handles[key]);
});
} catch (error) {
return false;
}
}
Example #2
Source File: utils.js From spring-boot-ecommerce with Apache License 2.0 | 7 votes |
export function isEventFromHandle(e, handles) {
try {
return Object.keys(handles).some(function (key) {
return e.target === findDOMNode(handles[key]);
});
} catch (error) {
return false;
}
}
Example #3
Source File: TabItems.jsx From ui-neumorphism with MIT License | 6 votes |
handleRef(item, check = false) {
if (!check) return
const tabItem = findDOMNode(item)
if (!tabItem) return
this.clearHeightTimeout()
this.timeout = setTimeout(() => {
const { height: stateHeight } = this.state
const height = tabItem.scrollHeight
if (height === stateHeight) return
this.setState({ height })
}, 250)
}
Example #4
Source File: index.js From Lynx with MIT License | 6 votes |
// Export Higher Order Sortable Element Component
export default function sortableHandle(WrappedComponent) {
var _class, _temp;
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { withRef: false };
return _temp = _class = function (_Component) {
_inherits(_class, _Component);
function _class() {
_classCallCheck(this, _class);
return _possibleConstructorReturn(this, (_class.__proto__ || _Object$getPrototypeOf(_class)).apply(this, arguments));
}
_createClass(_class, [{
key: 'componentDidMount',
value: function componentDidMount() {
var node = findDOMNode(this);
node.sortableHandle = true;
}
}, {
key: 'getWrappedInstance',
value: function getWrappedInstance() {
invariant(config.withRef, 'To access the wrapped instance, you need to pass in {withRef: true} as the second argument of the SortableHandle() call');
return this.refs.wrappedInstance;
}
}, {
key: 'render',
value: function render() {
var ref = config.withRef ? 'wrappedInstance' : null;
return React.createElement(WrappedComponent, _extends({ ref: ref }, this.props));
}
}]);
return _class;
}(Component), _class.displayName = provideDisplayName('sortableHandle', WrappedComponent), _temp;
}
Example #5
Source File: utils.js From Lynx with MIT License | 6 votes |
export function isEventFromHandle(e, handles) {
return Object.keys(handles).some(function (key) {
return e.target === findDOMNode(handles[key]);
});
}
Example #6
Source File: utils.js From the-eye-knows-the-garbage with MIT License | 6 votes |
export function isEventFromHandle(e, handles) {
return Object.keys(handles).some(function (key) {
return e.target === findDOMNode(handles[key]);
});
}
Example #7
Source File: index.js From qrn-remax-unir with MIT License | 6 votes |
findNodeHandle = component => {
let node;
try {
node = findDOMNode(component);
} catch (e) {}
return node;
}
Example #8
Source File: ItemMeasurer.js From dynamic-virtualized-list with MIT License | 6 votes |
componentDidMount() {
this._node = findDOMNode(this);
// Force sync measure for the initial mount.
// This is necessary to support the DynamicSizeList layout logic.
if (isSafari && this.props.size) {
this._measureItemAnimFrame = window.requestAnimationFrame(() => {
this._measureItem(false);
});
} else {
this._measureItem(false);
}
if (this.props.size) {
// Don't wait for positioning scrollbars when we have size
// This is needed triggering an event for remounting a post
this.positionScrollBars();
}
}
Example #9
Source File: Item.js From wix-style-react with MIT License | 6 votes |
cardSource = {
isDragging(props, monitor) {
const ids = getValuesByKey(monitor.getItem().data, 'id', 'children');
return ids.indexOf(props.id) > -1;
},
beginDrag(props, monitor, component) {
props.onDragStart && props.onDragStart(props);
const node = findDOMNode(component);
const clientRect = node.getBoundingClientRect();
let handleOffset = { x: 0, y: 0 };
// needed to fix dnd drag offset data
if (component.handleNode) {
handleOffset = calculateHandleOffset(
component.handleNode.getBoundingClientRect(),
clientRect,
);
}
return {
id: props.id,
index: props.index,
position: props.position,
data: props.item,
depth: props.depth,
// rect for entire component including children
clientRect,
handleOffset,
};
},
endDrag: (props, monitor) => {
mouse.lastX = 0;
props.dropItem(monitor.getItem());
props.onDragEnd && props.onDragEnd(props);
},
}
Example #10
Source File: DragUtils.js From wix-style-react with MIT License | 6 votes |
dragCoordinates = ({ monitor, component }) => {
const hoverBoundingRect = findDOMNode(component).getBoundingClientRect();
// Get vertical middle
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
const hoverMiddleX = (hoverBoundingRect.right - hoverBoundingRect.left) / 2;
// Determine mouse position
const clientOffset = monitor.getClientOffset();
// Get pixels to the top
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
const hoverClientX = clientOffset.x - hoverBoundingRect.left;
return {
hoverMiddleY,
clientOffset,
hoverClientY,
hoverMiddleX,
hoverClientX,
};
}
Example #11
Source File: index.js From atendimento-e-agilidade-medica-AAMed with MIT License | 6 votes |
componentDidMount() {
var node = findDOMNode(this.refs.btn);
var links = findDOMNode(this.refs.links);
node.addEventListener('click', () => {
links.classList.toggle('nav-active');
node.classList.toggle('toggle');
});
var lastScroll = 0;
const el = findDOMNode(this.refs.menu);
$(window).scroll(function (e) {
var st = $(this).scrollTop();
if (st > lastScroll) {
$(el).css('transform', 'translateY(-120px)');
} else {
$(el).css('transform', 'none');
}
lastScroll = st;
});
}
Example #12
Source File: flexbox.js From react-custom-scrollbars-2 with MIT License | 6 votes |
export default function createTests() {
let node;
beforeEach(() => {
node = document.createElement('div');
document.body.appendChild(node);
});
afterEach(() => {
unmountComponentAtNode(node);
document.body.removeChild(node);
});
describe('when scrollbars are in flexbox environment', () => {
it('should still work', done => {
class Root extends Component {
render() {
return (
<div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, display: 'flex', flexDirection: 'column' }}>
<Scrollbars ref={(ref) => { this.scrollbars = ref; }}>
<div style={{ width: 10000, height: 10000 }}/>
</Scrollbars>
</div>
);
}
}
render(<Root/>, node, function callback() {
setTimeout(() => {
const { scrollbars } = this;
const $scrollbars = findDOMNode(scrollbars);
const $view = scrollbars.view;
expect($scrollbars.clientHeight).toBeGreaterThan(0);
expect($view.clientHeight).toBeGreaterThan(0);
done();
}, 100);
});
});
});
}
Example #13
Source File: Tabs.jsx From ui-neumorphism with MIT License | 6 votes |
handleRef(ref, index) {
const tab = findDOMNode(ref)
if (!tab) return
const { tabsMeta } = this.state
const { width } = tab.getBoundingClientRect()
if (tabsMeta[index] === width) return
this.setState({ tabsMeta: { ...tabsMeta, [index]: width } })
}
Example #14
Source File: Portal.js From tonic-ui with MIT License | 5 votes |
function getContainer(container) {
container = typeof container === 'function' ? container() : container;
return findDOMNode(container);
}
Example #15
Source File: virtual-list.jsx From intergalactic with MIT License | 5 votes |
Demo = () => {
const [data, updateDate] = useState(list);
const innerRef = useRef();
const ref = (node) => {
node = findDOMNode(node);
if (node) {
innerRef.current = node.querySelector('.ReactVirtualized__Grid__innerScrollContainer');
}
};
return (
<Flex direction="column" inline>
<Flex alignItems="center" mb={2}>
<Button
onClick={() => {
updateDate(data.concat(undefined));
}}
>
ADD
</Button>
<Button ml="10px" onClick={() => updateDate(data.slice(0, -1))}>
REMOVE
</Button>
<Text bold ml="10px">
Count: {data.length}
</Text>
</Flex>
<Box h={500}>
{data.length ? (
<ScrollArea inner={innerRef}>
<ScrollArea.Container
ref={ref}
tag={List}
height={500}
rowCount={data.length}
width={500}
rowHeight={120}
rowRenderer={renderRow}
/>
<ScrollArea.Bar orientation="vertical" />
</ScrollArea>
) : null}
</Box>
</Flex>
);
}
Example #16
Source File: withResize.jsx From ui-neumorphism with MIT License | 5 votes |
withResize = (WrappedComponent, config = {}) => {
return class withResize extends React.Component {
static displayName = `WithResize(${
WrappedComponent.displayName || WrappedComponent.name || 'Component'
})`
constructor(props) {
super(props)
this.state = {
height: null,
width: null
}
this.node = null
this.resizeObserver = null
this.updateDimensions = this.updateDimensions.bind(this)
}
componentDidMount() {
const { onlyWidth, onlyHeight } = config
const configNotActive = !onlyWidth && !onlyHeight
// eslint-disable-next-line no-undef
this.resizeObserver = new ResizeObserver((entries) => {
const { width: currentWidth, height: currentHeight } = this.state
entries.forEach((entry) => {
const { width, height } = (entry && entry.contentRect) || {}
const isWidthChanged = currentWidth !== width
const isHeightChanged = currentHeight !== height
const isSizeChanged = isHeightChanged || isWidthChanged
if (onlyWidth && isWidthChanged) {
this.updateDimensions({ width })
} else if (onlyHeight && isHeightChanged) {
this.updateDimensions({ height })
} else if (isSizeChanged && configNotActive) {
this.updateDimensions({ width, height })
}
})
})
this.resizeObserver.observe(this.node)
}
componentWillUnmount() {
if (this.resizeObserver) {
this.resizeObserver.disconnect()
}
}
updateDimensions = (dimensions) => {
this.setState({ ...this.state, ...dimensions })
}
getCurrentSize() {
const { width } = this.state
return width > 1904
? 'xl'
: width > 1264
? 'lg'
: width > 960
? 'md'
: width > 600
? 'sm'
: 'xs'
}
render() {
const { width, height } = this.state
return (
<WrappedComponent
ref={(ref) => (this.node = findDOMNode(ref))}
dimensions={{ width, height }}
size={this.getCurrentSize()}
{...this.props}
/>
)
}
}
}
Example #17
Source File: withClickOutside.jsx From ui-neumorphism with MIT License | 5 votes |
withClickOutside = (WrappedComponent) => {
const componentName =
WrappedComponent.displayName || WrappedComponent.name || 'Component'
return class WithClickOutside extends React.Component {
static displayName = `WithClickOutside(${componentName})`
constructor(props) {
super(props)
this.node = null
this.handleClick = this.handleClick.bind(this)
}
componentDidMount() {
document.addEventListener('click', this.handleClick)
}
componentWillUnmount() {
document.removeEventListener('click', this.handleClick)
}
handleClick = (e) => {
const parentNode = findDOMNode(this.node)
const isClickInside = findClickInside(e, parentNode)
if (isClickInside) {
this.clickHandler(e, 'Inside')
} else {
this.clickHandler(e, 'Outside')
}
}
clickHandler(e, type = 'Outside') {
if (typeof this.node.props[`handleClick${type}`] === 'function') {
this.node.props[`handleClick${type}`](e)
return
}
if (typeof this.node[`handleClick${type}`] === 'function') {
this.node[`handleClick${type}`](e)
return
}
if (type === 'Outside') {
throw new Error(
`${componentName}: needs a handleClickOutside function to handle outside clicks`
)
}
}
render() {
return (
<WrappedComponent ref={(ref) => (this.node = ref)} {...this.props} />
)
}
}
}
Example #18
Source File: Item.js From wix-style-react with MIT License | 5 votes |
cardTarget = {
hover(props, monitor, component) {
if (!component) {
return;
}
const item = monitor.getItem();
// the item being dragged
const { position: prevPosition, data: dragItem, depth: dragDepth } = item;
// props for component underneath drag
const { position: hoverPosition, maxDepth } = props;
const hoverDepth = hoverPosition.length - 1;
const totalDepth = hoverDepth + dragDepth;
// don't exceed max depth
if (totalDepth > maxDepth) {
return;
}
const hoverNode = findDOMNode(component);
const nextPosition = determineHorizontalPosition({
monitor,
props,
hoverNode,
});
if (
!allowItemMove({ prevPosition, nextPosition, monitor, hoverNode, props })
) {
return;
}
// this is where the actual move happens
const nextPos = props.moveItem({
dragItem,
prevPosition,
nextPosition,
});
item.prevPosition = prevPosition;
item.prevIndex = item.index;
// note: we're mutating the monitor item here!
// generally it's better to avoid mutations,
// but it's good here for the sake of performance
// to avoid expensive index searches
item.position = nextPos;
item.index = nextPos[nextPos.length - 1];
},
}
Example #19
Source File: Item.js From wix-style-react with MIT License | 5 votes |
render() {
const {
item,
position,
children,
isPlaceholder,
connectDragSource,
connectDropTarget,
isRenderDraggingChildren,
useDragHandle,
renderItem,
theme,
} = this.props;
const shouldRenderChildren = !isPlaceholder || isRenderDraggingChildren;
// params passed to renderItem callback
const renderParams = {
item,
isPlaceholder,
isPreview: false,
depth: position.length,
};
const classes = classNames('nestable-item', theme && theme.item);
if (useDragHandle) {
renderParams.connectDragSource = handle => {
const handleWithRef = React.cloneElement(handle, {
ref: node => (this.handleNode = findDOMNode(node)),
});
return connectDragSource(handleWithRef);
};
return connectDropTarget(
<div className={classes} data-hook="nestable-item">
{renderItem(renderParams)}
{shouldRenderChildren && children}
</div>,
);
}
return connectDropTarget(
connectDragSource(
<div className={classes} data-hook="nestable-item">
{renderItem(renderParams)}
{shouldRenderChildren && children}
</div>,
),
);
}
Example #20
Source File: MainContainer.jsx From ui-neumorphism with MIT License | 5 votes |
render() {
const { isHome } = this
const { size } = this.props
const { dark, open } = this.state
const isSmall = size === 'sm' || size === 'xs'
return (
<main className={`theme--${dark ? 'dark' : 'light'}`}>
<Card
flat
dark={dark}
className={`main-container ${isSmall ? 'main-container-sm' : ''}`}
>
<Card>
<Topbar
size={size}
dark={dark}
onClick={this.toggleTheme}
onMenuClick={this.toggleSidebar}
/>
<Divider dense dark={dark} />
<Card flat className='main-content'>
<Sidebar
dark={dark}
open={open}
size={size}
onClick={this.onSidebarClick}
onOutsideClick={this.toggleSidebar}
/>
<Card
flat
id='mainView'
ref={(ref) => (this.mainView = findDOMNode(ref))}
className={`main-view main-view--${
!isSmall ? 'large' : 'small'
} ${isHome ? 'main-view--home' : ''} ${
open ? 'main-view--open' : ''
}`}
>
<Switch>
{routes.map((route) => (
<Route
exact
key={route.id}
path={route.path}
component={() => <route.component dark={dark} />}
/>
))}
</Switch>
</Card>
{isSmall || isHome ? null : <RightBar dark={dark} size={size} />}
</Card>
</Card>
</Card>
</main>
)
}
Example #21
Source File: index.js From brisque-2.0-desktop with MIT License | 5 votes |
componentDidUpdate(props, state) {
const { selectedFilter } = this.state
if (selectedFilter !== state.selectedFilter) {
/* eslint-disable-next-line */
findDOMNode(this.bodyRef.current).scrollTo(0, 0)
}
}
Example #22
Source File: autoHeight.js From react-custom-scrollbars-2 with MIT License | 4 votes |
export default function createTests(scrollbarWidth, envScrollbarWidth) {
describe('autoHeight', () => {
let node;
beforeEach(() => {
node = document.createElement('div');
document.body.appendChild(node);
});
afterEach(() => {
unmountComponentAtNode(node);
document.body.removeChild(node);
});
describe('when rendered', () => {
it('should have min-height and max-height', done => {
render((
<Scrollbars
autoHeight
autoHeightMin={0}
autoHeightMax={100}>
<div style={{ width: 200, height: 200 }}/>
</Scrollbars>
), node, function callback() {
const scrollbars = findDOMNode(this);
expect(scrollbars.style.position).toEqual('relative');
expect(scrollbars.style.minHeight).toEqual('0px');
expect(scrollbars.style.maxHeight).toEqual('100px');
expect(this.view.style.position).toEqual('relative');
expect(this.view.style.minHeight).toEqual(`${scrollbarWidth}px`);
expect(this.view.style.maxHeight).toEqual(`${100 + scrollbarWidth}px`);
done();
});
});
});
describe('when native scrollbars have a width', () => {
if (!scrollbarWidth) return;
it('hides native scrollbars', done => {
render((
<Scrollbars
autoHeight
autoHeightMax={100}>
<div style={{ width: 200, height: 200 }}/>
</Scrollbars>
), node, function callback() {
const width = `-${scrollbarWidth}px`;
expect(this.view.style.marginRight).toEqual(width);
expect(this.view.style.marginBottom).toEqual(width);
done();
});
});
});
describe('when native scrollbars have no width', () => {
if (scrollbarWidth) return;
it('hides bars', done => {
render((
<Scrollbars
autoHeight
autoHeightMax={100}>
<div style={{ width: 200, height: 200 }}/>
</Scrollbars>
), node, function callback() {
setTimeout(() => {
expect(this.trackVertical.style.display).toEqual('none');
expect(this.trackHorizontal.style.display).toEqual('none');
done();
}, 100);
});
});
});
describe('when content is smaller than maxHeight', () => {
it('should have the content\'s height', done => {
render((
<Scrollbars
autoHeight
autoHeightMax={100}>
<div style={{ height: 50 }}/>
</Scrollbars>
), node, function callback() {
setTimeout(() => {
const scrollbars = findDOMNode(this);
expect(scrollbars.clientHeight).toEqual(50 + (envScrollbarWidth - scrollbarWidth));
expect(this.view.clientHeight).toEqual(50);
expect(this.view.scrollHeight).toEqual(50);
expect(this.thumbVertical.clientHeight).toEqual(0);
done();
}, 100);
});
});
});
describe('when content is larger than maxHeight', () => {
it('should show scrollbars', done => {
render((
<Scrollbars
autoHeight
autoHeightMax={100}>
<div style={{ height: 200 }}/>
</Scrollbars>
), node, function callback() {
setTimeout(() => {
const scrollbars = findDOMNode(this);
expect(scrollbars.clientHeight).toEqual(100);
expect(this.view.clientHeight).toEqual(100 - (envScrollbarWidth - scrollbarWidth));
expect(this.view.scrollHeight).toEqual(200);
if (scrollbarWidth) {
// 100 / 200 * 96 = 48
expect(this.thumbVertical.clientHeight).toEqual(48);
}
done();
}, 100);
});
});
});
describe('when minHeight is greater than 0', () => {
it('should have height greater than 0', done => {
render((
<Scrollbars
autoHeight
autoHeightMin={100}
autoHeightMax={200}>
<div/>
</Scrollbars>
), node, function callback() {
setTimeout(() => {
const scrollbars = findDOMNode(this);
expect(scrollbars.clientHeight).toEqual(100);
expect(this.view.clientHeight).toEqual(100 - (envScrollbarWidth - scrollbarWidth));
expect(this.thumbVertical.clientHeight).toEqual(0);
done();
}, 100);
});
});
});
describe('when using perecentages', () => {
it('should use calc', done => {
class Root extends Component {
render() {
return (
<div style={{ width: 500, height: 500 }}>
<Scrollbars
ref={(ref) => { this.scrollbars = ref; }}
autoHeight
autoHeightMin="50%"
autoHeightMax="100%">
<div style={{ width: 200, height: 200 }}/>
</Scrollbars>
</div>
);
}
}
render(<Root/>, node, function callback() {
setTimeout(() => {
const $scrollbars = findDOMNode(this.scrollbars);
const view = this.scrollbars.view;
expect($scrollbars.clientWidth).toEqual(500);
expect($scrollbars.clientHeight).toEqual(250);
expect($scrollbars.style.position).toEqual('relative');
expect($scrollbars.style.minHeight).toEqual('50%');
expect($scrollbars.style.maxHeight).toEqual('100%');
expect(view.style.position).toEqual('relative');
expect(view.style.minHeight).toEqual(`calc(50% + ${scrollbarWidth}px)`);
expect(view.style.maxHeight).toEqual(`calc(100% + ${scrollbarWidth}px)`);
done();
}, 100);
});
});
});
describe('when using other units', () => {
it('should use calc', done => {
render((
<Scrollbars
autoHeight
autoHeightMin="10em"
autoHeightMax="100em">
<div style={{ width: 200, height: 200 }}/>
</Scrollbars>
), node, function callback() {
const scrollbars = findDOMNode(this);
expect(scrollbars.style.position).toEqual('relative');
expect(scrollbars.style.minHeight).toEqual('10em');
expect(scrollbars.style.maxHeight).toEqual('100em');
expect(this.view.style.position).toEqual('relative');
expect(this.view.style.minHeight).toEqual(`calc(10em + ${scrollbarWidth}px)`);
expect(this.view.style.maxHeight).toEqual(`calc(100em + ${scrollbarWidth}px)`);
done();
});
});
});
});
}
Example #23
Source File: index.js From Lynx with MIT License | 4 votes |
_initialiseProps = function _initialiseProps() {
var _this5 = this;
this.onMouseEnter = function (e) {
_this5.fireEvents('onMouseEnter', e);
_this5.delaySetPopupVisible(true, _this5.props.mouseEnterDelay);
};
this.onMouseLeave = function (e) {
_this5.fireEvents('onMouseLeave', e);
_this5.delaySetPopupVisible(false, _this5.props.mouseLeaveDelay);
};
this.onPopupMouseEnter = function () {
_this5.clearDelayTimer();
};
this.onPopupMouseLeave = function (e) {
// https://github.com/react-component/trigger/pull/13
// react bug?
if (e.relatedTarget && !e.relatedTarget.setTimeout && _this5._component && _this5._component.getPopupDomNode && contains(_this5._component.getPopupDomNode(), e.relatedTarget)) {
return;
}
_this5.delaySetPopupVisible(false, _this5.props.mouseLeaveDelay);
};
this.onFocus = function (e) {
_this5.fireEvents('onFocus', e);
// incase focusin and focusout
_this5.clearDelayTimer();
if (_this5.isFocusToShow()) {
_this5.focusTime = Date.now();
_this5.delaySetPopupVisible(true, _this5.props.focusDelay);
}
};
this.onMouseDown = function (e) {
_this5.fireEvents('onMouseDown', e);
_this5.preClickTime = Date.now();
};
this.onTouchStart = function (e) {
_this5.fireEvents('onTouchStart', e);
_this5.preTouchTime = Date.now();
};
this.onBlur = function (e) {
_this5.fireEvents('onBlur', e);
_this5.clearDelayTimer();
if (_this5.isBlurToHide()) {
_this5.delaySetPopupVisible(false, _this5.props.blurDelay);
}
};
this.onContextMenu = function (e) {
e.preventDefault();
_this5.fireEvents('onContextMenu', e);
_this5.setPopupVisible(true);
};
this.onContextMenuClose = function () {
if (_this5.isContextMenuToShow()) {
_this5.close();
}
};
this.onClick = function (event) {
_this5.fireEvents('onClick', event);
// focus will trigger click
if (_this5.focusTime) {
var preTime = void 0;
if (_this5.preClickTime && _this5.preTouchTime) {
preTime = Math.min(_this5.preClickTime, _this5.preTouchTime);
} else if (_this5.preClickTime) {
preTime = _this5.preClickTime;
} else if (_this5.preTouchTime) {
preTime = _this5.preTouchTime;
}
if (Math.abs(preTime - _this5.focusTime) < 20) {
return;
}
_this5.focusTime = 0;
}
_this5.preClickTime = 0;
_this5.preTouchTime = 0;
event.preventDefault();
var nextVisible = !_this5.state.popupVisible;
if (_this5.isClickToHide() && !nextVisible || nextVisible && _this5.isClickToShow()) {
_this5.setPopupVisible(!_this5.state.popupVisible);
}
};
this.onDocumentClick = function (event) {
if (_this5.props.mask && !_this5.props.maskClosable) {
return;
}
var target = event.target;
var root = findDOMNode(_this5);
var popupNode = _this5.getPopupDomNode();
if (!contains(root, target) && !contains(popupNode, target)) {
_this5.close();
}
};
this.getRootDomNode = function () {
return findDOMNode(_this5);
};
this.getPopupClassNameFromAlign = function (align) {
var className = [];
var props = _this5.props;
var popupPlacement = props.popupPlacement,
builtinPlacements = props.builtinPlacements,
prefixCls = props.prefixCls;
if (popupPlacement && builtinPlacements) {
className.push(getPopupClassNameFromAlign(builtinPlacements, prefixCls, align));
}
if (props.getPopupClassNameFromAlign) {
className.push(props.getPopupClassNameFromAlign(align));
}
return className.join(' ');
};
this.getComponent = function () {
var props = _this5.props,
state = _this5.state;
var mouseProps = {};
if (_this5.isMouseEnterToShow()) {
mouseProps.onMouseEnter = _this5.onPopupMouseEnter;
}
if (_this5.isMouseLeaveToHide()) {
mouseProps.onMouseLeave = _this5.onPopupMouseLeave;
}
return React.createElement(
Popup,
_extends({
prefixCls: props.prefixCls,
destroyPopupOnHide: props.destroyPopupOnHide,
visible: state.popupVisible,
className: props.popupClassName,
action: props.action,
align: _this5.getPopupAlign(),
onAlign: props.onPopupAlign,
animation: props.popupAnimation,
getClassNameFromAlign: _this5.getPopupClassNameFromAlign
}, mouseProps, {
getRootDomNode: _this5.getRootDomNode,
style: props.popupStyle,
mask: props.mask,
zIndex: props.zIndex,
transitionName: props.popupTransitionName,
maskAnimation: props.maskAnimation,
maskTransitionName: props.maskTransitionName,
ref: _this5.savePopup
}),
typeof props.popup === 'function' ? props.popup() : props.popup
);
};
this.getContainer = function () {
var props = _this5.props;
var popupContainer = document.createElement('div');
// Make sure default popup container will never cause scrollbar appearing
// https://github.com/react-component/trigger/issues/41
popupContainer.style.position = 'absolute';
popupContainer.style.top = '0';
popupContainer.style.left = '0';
popupContainer.style.width = '100%';
var mountNode = props.getPopupContainer ? props.getPopupContainer(findDOMNode(_this5)) : props.getDocument().body;
mountNode.appendChild(popupContainer);
return popupContainer;
};
this.handlePortalUpdate = function () {
if (_this5.prevPopupVisible !== _this5.state.popupVisible) {
_this5.props.afterPopupVisibleChange(_this5.state.popupVisible);
}
};
this.savePopup = function (node) {
_this5._component = node;
};
}
Example #24
Source File: index.js From Lynx with MIT License | 4 votes |
// Export Higher Order Sortable Container Component
export default function sortableContainer(WrappedComponent) {
var _class, _temp;
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { withRef: false };
return _temp = _class = function (_Component) {
_inherits(_class, _Component);
function _class(props) {
_classCallCheck(this, _class);
var _this = _possibleConstructorReturn(this, (_class.__proto__ || _Object$getPrototypeOf(_class)).call(this, props));
_this.handleStart = function (event) {
var _this$props = _this.props,
distance = _this$props.distance,
shouldCancelStart = _this$props.shouldCancelStart;
if (event.button === 2 || shouldCancelStart(event)) {
return false;
}
_this._touched = true;
_this._pos = getPosition(event);
var node = closest(event.target, function (el) {
return el.sortableInfo != null;
});
if (node && node.sortableInfo && _this.nodeIsChild(node) && !_this.state.sorting) {
var useDragHandle = _this.props.useDragHandle;
var _node$sortableInfo = node.sortableInfo,
index = _node$sortableInfo.index,
collection = _node$sortableInfo.collection;
if (useDragHandle && !closest(event.target, function (el) {
return el.sortableHandle != null;
})) return;
_this.manager.active = { index: index, collection: collection };
/*
* Fixes a bug in Firefox where the :active state of anchor tags
* prevent subsequent 'mousemove' events from being fired
* (see https://github.com/clauderic/react-sortable-hoc/issues/118)
*/
if (!isTouchEvent(event) && event.target.tagName.toLowerCase() === 'a') {
event.preventDefault();
}
if (!distance) {
if (_this.props.pressDelay === 0) {
_this.handlePress(event);
} else {
_this.pressTimer = setTimeout(function () {
return _this.handlePress(event);
}, _this.props.pressDelay);
}
}
}
};
_this.nodeIsChild = function (node) {
return node.sortableInfo.manager === _this.manager;
};
_this.handleMove = function (event) {
var _this$props2 = _this.props,
distance = _this$props2.distance,
pressThreshold = _this$props2.pressThreshold;
if (!_this.state.sorting && _this._touched) {
var position = getPosition(event);
var delta = _this._delta = {
x: _this._pos.x - position.x,
y: _this._pos.y - position.y
};
var combinedDelta = Math.abs(delta.x) + Math.abs(delta.y);
if (!distance && (!pressThreshold || pressThreshold && combinedDelta >= pressThreshold)) {
clearTimeout(_this.cancelTimer);
_this.cancelTimer = setTimeout(_this.cancel, 0);
} else if (distance && combinedDelta >= distance && _this.manager.isActive()) {
_this.handlePress(event);
}
}
};
_this.handleEnd = function () {
var distance = _this.props.distance;
_this._touched = false;
if (!distance) {
_this.cancel();
}
};
_this.cancel = function () {
if (!_this.state.sorting) {
clearTimeout(_this.pressTimer);
_this.manager.active = null;
}
};
_this.handlePress = function (event) {
var active = _this.manager.getActive();
if (active) {
var _this$props3 = _this.props,
axis = _this$props3.axis,
getHelperDimensions = _this$props3.getHelperDimensions,
helperClass = _this$props3.helperClass,
hideSortableGhost = _this$props3.hideSortableGhost,
onSortStart = _this$props3.onSortStart,
useWindowAsScrollContainer = _this$props3.useWindowAsScrollContainer;
var node = active.node,
collection = active.collection;
var index = node.sortableInfo.index;
var margin = getElementMargin(node);
var containerBoundingRect = _this.container.getBoundingClientRect();
var dimensions = getHelperDimensions({ index: index, node: node, collection: collection });
_this.node = node;
_this.margin = margin;
_this.width = dimensions.width;
_this.height = dimensions.height;
_this.marginOffset = {
x: _this.margin.left + _this.margin.right,
y: Math.max(_this.margin.top, _this.margin.bottom)
};
_this.boundingClientRect = node.getBoundingClientRect();
_this.containerBoundingRect = containerBoundingRect;
_this.index = index;
_this.newIndex = index;
_this.axis = {
x: axis.indexOf('x') >= 0,
y: axis.indexOf('y') >= 0
};
_this.offsetEdge = getEdgeOffset(node, _this.container);
_this.initialOffset = getPosition(event);
_this.initialScroll = {
top: _this.container.scrollTop,
left: _this.container.scrollLeft
};
_this.initialWindowScroll = {
top: window.pageYOffset,
left: window.pageXOffset
};
var fields = node.querySelectorAll('input, textarea, select');
var clonedNode = node.cloneNode(true);
var clonedFields = [].concat(_toConsumableArray(clonedNode.querySelectorAll('input, textarea, select'))); // Convert NodeList to Array
clonedFields.forEach(function (field, index) {
if (field.type !== 'file' && fields[index]) {
field.value = fields[index].value;
}
});
_this.helper = _this.document.body.appendChild(clonedNode);
_this.helper.style.position = 'fixed';
_this.helper.style.top = _this.boundingClientRect.top - margin.top + 'px';
_this.helper.style.left = _this.boundingClientRect.left - margin.left + 'px';
_this.helper.style.width = _this.width + 'px';
_this.helper.style.height = _this.height + 'px';
_this.helper.style.boxSizing = 'border-box';
_this.helper.style.pointerEvents = 'none';
if (hideSortableGhost) {
_this.sortableGhost = node;
node.style.visibility = 'hidden';
node.style.opacity = 0;
}
_this.minTranslate = {};
_this.maxTranslate = {};
if (_this.axis.x) {
_this.minTranslate.x = (useWindowAsScrollContainer ? 0 : containerBoundingRect.left) - _this.boundingClientRect.left - _this.width / 2;
_this.maxTranslate.x = (useWindowAsScrollContainer ? _this.contentWindow.innerWidth : containerBoundingRect.left + containerBoundingRect.width) - _this.boundingClientRect.left - _this.width / 2;
}
if (_this.axis.y) {
_this.minTranslate.y = (useWindowAsScrollContainer ? 0 : containerBoundingRect.top) - _this.boundingClientRect.top - _this.height / 2;
_this.maxTranslate.y = (useWindowAsScrollContainer ? _this.contentWindow.innerHeight : containerBoundingRect.top + containerBoundingRect.height) - _this.boundingClientRect.top - _this.height / 2;
}
if (helperClass) {
var _this$helper$classLis;
(_this$helper$classLis = _this.helper.classList).add.apply(_this$helper$classLis, _toConsumableArray(helperClass.split(' ')));
}
_this.listenerNode = event.touches ? node : _this.contentWindow;
events.move.forEach(function (eventName) {
return _this.listenerNode.addEventListener(eventName, _this.handleSortMove, false);
});
events.end.forEach(function (eventName) {
return _this.listenerNode.addEventListener(eventName, _this.handleSortEnd, false);
});
_this.setState({
sorting: true,
sortingIndex: index
});
if (onSortStart) {
onSortStart({ node: node, index: index, collection: collection }, event);
}
}
};
_this.handleSortMove = function (event) {
var onSortMove = _this.props.onSortMove;
event.preventDefault(); // Prevent scrolling on mobile
_this.updatePosition(event);
_this.animateNodes();
_this.autoscroll();
if (onSortMove) {
onSortMove(event);
}
};
_this.handleSortEnd = function (event) {
var _this$props4 = _this.props,
hideSortableGhost = _this$props4.hideSortableGhost,
onSortEnd = _this$props4.onSortEnd;
var collection = _this.manager.active.collection;
// Remove the event listeners if the node is still in the DOM
if (_this.listenerNode) {
events.move.forEach(function (eventName) {
return _this.listenerNode.removeEventListener(eventName, _this.handleSortMove);
});
events.end.forEach(function (eventName) {
return _this.listenerNode.removeEventListener(eventName, _this.handleSortEnd);
});
}
// Remove the helper from the DOM
_this.helper.parentNode.removeChild(_this.helper);
if (hideSortableGhost && _this.sortableGhost) {
_this.sortableGhost.style.visibility = '';
_this.sortableGhost.style.opacity = '';
}
var nodes = _this.manager.refs[collection];
for (var i = 0, len = nodes.length; i < len; i++) {
var node = nodes[i];
var el = node.node;
// Clear the cached offsetTop / offsetLeft value
node.edgeOffset = null;
// Remove the transforms / transitions
el.style[vendorPrefix + 'Transform'] = '';
el.style[vendorPrefix + 'TransitionDuration'] = '';
}
// Stop autoscroll
clearInterval(_this.autoscrollInterval);
_this.autoscrollInterval = null;
// Update state
_this.manager.active = null;
_this.setState({
sorting: false,
sortingIndex: null
});
if (typeof onSortEnd === 'function') {
onSortEnd({
oldIndex: _this.index,
newIndex: _this.newIndex,
collection: collection
}, event);
}
_this._touched = false;
};
_this.autoscroll = function () {
var translate = _this.translate;
var direction = {
x: 0,
y: 0
};
var speed = {
x: 1,
y: 1
};
var acceleration = {
x: 10,
y: 10
};
if (translate.y >= _this.maxTranslate.y - _this.height / 2) {
direction.y = 1; // Scroll Down
speed.y = acceleration.y * Math.abs((_this.maxTranslate.y - _this.height / 2 - translate.y) / _this.height);
} else if (translate.x >= _this.maxTranslate.x - _this.width / 2) {
direction.x = 1; // Scroll Right
speed.x = acceleration.x * Math.abs((_this.maxTranslate.x - _this.width / 2 - translate.x) / _this.width);
} else if (translate.y <= _this.minTranslate.y + _this.height / 2) {
direction.y = -1; // Scroll Up
speed.y = acceleration.y * Math.abs((translate.y - _this.height / 2 - _this.minTranslate.y) / _this.height);
} else if (translate.x <= _this.minTranslate.x + _this.width / 2) {
direction.x = -1; // Scroll Left
speed.x = acceleration.x * Math.abs((translate.x - _this.width / 2 - _this.minTranslate.x) / _this.width);
}
if (_this.autoscrollInterval) {
clearInterval(_this.autoscrollInterval);
_this.autoscrollInterval = null;
_this.isAutoScrolling = false;
}
if (direction.x !== 0 || direction.y !== 0) {
_this.autoscrollInterval = setInterval(function () {
_this.isAutoScrolling = true;
var offset = {
left: 1 * speed.x * direction.x,
top: 1 * speed.y * direction.y
};
_this.scrollContainer.scrollTop += offset.top;
_this.scrollContainer.scrollLeft += offset.left;
_this.translate.x += offset.left;
_this.translate.y += offset.top;
_this.animateNodes();
}, 5);
}
};
_this.manager = new Manager();
_this.events = {
start: _this.handleStart,
move: _this.handleMove,
end: _this.handleEnd
};
invariant(!(props.distance && props.pressDelay), 'Attempted to set both `pressDelay` and `distance` on SortableContainer, you may only use one or the other, not both at the same time.');
_this.state = {};
return _this;
}
_createClass(_class, [{
key: 'getChildContext',
value: function getChildContext() {
return {
manager: this.manager
};
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
var _this2 = this;
var useWindowAsScrollContainer = this.props.useWindowAsScrollContainer;
/*
* Set our own default rather than using defaultProps because Jest
* snapshots will serialize window, causing a RangeError
* https://github.com/clauderic/react-sortable-hoc/issues/249
*/
var container = this.getContainer();
_Promise.resolve(container).then(function (containerNode) {
_this2.container = containerNode;
_this2.document = _this2.container.ownerDocument || document;
var contentWindow = _this2.props.contentWindow || _this2.document.defaultView || window;
_this2.contentWindow = typeof contentWindow === 'function' ? contentWindow() : contentWindow;
_this2.scrollContainer = useWindowAsScrollContainer ? _this2.document.scrollingElement || _this2.document.documentElement : _this2.container;
var _loop = function _loop(key) {
if (_this2.events.hasOwnProperty(key)) {
events[key].forEach(function (eventName) {
return _this2.container.addEventListener(eventName, _this2.events[key], false);
});
}
};
for (var key in _this2.events) {
_loop(key);
}
});
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
var _this3 = this;
if (this.container) {
var _loop2 = function _loop2(key) {
if (_this3.events.hasOwnProperty(key)) {
events[key].forEach(function (eventName) {
return _this3.container.removeEventListener(eventName, _this3.events[key]);
});
}
};
for (var key in this.events) {
_loop2(key);
}
}
}
}, {
key: 'getLockPixelOffsets',
value: function getLockPixelOffsets() {
var width = this.width,
height = this.height;
var lockOffset = this.props.lockOffset;
var offsets = Array.isArray(lockOffset) ? lockOffset : [lockOffset, lockOffset];
invariant(offsets.length === 2, 'lockOffset prop of SortableContainer should be a single ' + 'value or an array of exactly two values. Given %s', lockOffset);
var _offsets = _slicedToArray(offsets, 2),
minLockOffset = _offsets[0],
maxLockOffset = _offsets[1];
return [getLockPixelOffset({ lockOffset: minLockOffset, width: width, height: height }), getLockPixelOffset({ lockOffset: maxLockOffset, width: width, height: height })];
}
}, {
key: 'updatePosition',
value: function updatePosition(event) {
var _props = this.props,
lockAxis = _props.lockAxis,
lockToContainerEdges = _props.lockToContainerEdges;
var offset = getPosition(event);
var translate = {
x: offset.x - this.initialOffset.x,
y: offset.y - this.initialOffset.y
};
// Adjust for window scroll
translate.y -= window.pageYOffset - this.initialWindowScroll.top;
translate.x -= window.pageXOffset - this.initialWindowScroll.left;
this.translate = translate;
if (lockToContainerEdges) {
var _getLockPixelOffsets = this.getLockPixelOffsets(),
_getLockPixelOffsets2 = _slicedToArray(_getLockPixelOffsets, 2),
minLockOffset = _getLockPixelOffsets2[0],
maxLockOffset = _getLockPixelOffsets2[1];
var minOffset = {
x: this.width / 2 - minLockOffset.x,
y: this.height / 2 - minLockOffset.y
};
var maxOffset = {
x: this.width / 2 - maxLockOffset.x,
y: this.height / 2 - maxLockOffset.y
};
translate.x = limit(this.minTranslate.x + minOffset.x, this.maxTranslate.x - maxOffset.x, translate.x);
translate.y = limit(this.minTranslate.y + minOffset.y, this.maxTranslate.y - maxOffset.y, translate.y);
}
if (lockAxis === 'x') {
translate.y = 0;
} else if (lockAxis === 'y') {
translate.x = 0;
}
this.helper.style[vendorPrefix + 'Transform'] = 'translate3d(' + translate.x + 'px,' + translate.y + 'px, 0)';
}
}, {
key: 'animateNodes',
value: function animateNodes() {
var _props2 = this.props,
transitionDuration = _props2.transitionDuration,
hideSortableGhost = _props2.hideSortableGhost,
onSortOver = _props2.onSortOver;
var nodes = this.manager.getOrderedRefs();
var containerScrollDelta = {
left: this.container.scrollLeft - this.initialScroll.left,
top: this.container.scrollTop - this.initialScroll.top
};
var sortingOffset = {
left: this.offsetEdge.left + this.translate.x + containerScrollDelta.left,
top: this.offsetEdge.top + this.translate.y + containerScrollDelta.top
};
var windowScrollDelta = {
top: window.pageYOffset - this.initialWindowScroll.top,
left: window.pageXOffset - this.initialWindowScroll.left
};
var prevIndex = this.newIndex;
this.newIndex = null;
for (var i = 0, len = nodes.length; i < len; i++) {
var node = nodes[i].node;
var index = node.sortableInfo.index;
var width = node.offsetWidth;
var height = node.offsetHeight;
var offset = {
width: this.width > width ? width / 2 : this.width / 2,
height: this.height > height ? height / 2 : this.height / 2
};
var translate = {
x: 0,
y: 0
};
var edgeOffset = nodes[i].edgeOffset;
// If we haven't cached the node's offsetTop / offsetLeft value
if (!edgeOffset) {
nodes[i].edgeOffset = edgeOffset = getEdgeOffset(node, this.container);
}
// Get a reference to the next and previous node
var nextNode = i < nodes.length - 1 && nodes[i + 1];
var prevNode = i > 0 && nodes[i - 1];
// Also cache the next node's edge offset if needed.
// We need this for calculating the animation in a grid setup
if (nextNode && !nextNode.edgeOffset) {
nextNode.edgeOffset = getEdgeOffset(nextNode.node, this.container);
}
// If the node is the one we're currently animating, skip it
if (index === this.index) {
if (hideSortableGhost) {
/*
* With windowing libraries such as `react-virtualized`, the sortableGhost
* node may change while scrolling down and then back up (or vice-versa),
* so we need to update the reference to the new node just to be safe.
*/
this.sortableGhost = node;
node.style.visibility = 'hidden';
node.style.opacity = 0;
}
continue;
}
if (transitionDuration) {
node.style[vendorPrefix + 'TransitionDuration'] = transitionDuration + 'ms';
}
if (this.axis.x) {
if (this.axis.y) {
// Calculations for a grid setup
if (index < this.index && (sortingOffset.left + windowScrollDelta.left - offset.width <= edgeOffset.left && sortingOffset.top + windowScrollDelta.top <= edgeOffset.top + offset.height || sortingOffset.top + windowScrollDelta.top + offset.height <= edgeOffset.top)) {
// If the current node is to the left on the same row, or above the node that's being dragged
// then move it to the right
translate.x = this.width + this.marginOffset.x;
if (edgeOffset.left + translate.x > this.containerBoundingRect.width - offset.width) {
// If it moves passed the right bounds, then animate it to the first position of the next row.
// We just use the offset of the next node to calculate where to move, because that node's original position
// is exactly where we want to go
translate.x = nextNode.edgeOffset.left - edgeOffset.left;
translate.y = nextNode.edgeOffset.top - edgeOffset.top;
}
if (this.newIndex === null) {
this.newIndex = index;
}
} else if (index > this.index && (sortingOffset.left + windowScrollDelta.left + offset.width >= edgeOffset.left && sortingOffset.top + windowScrollDelta.top + offset.height >= edgeOffset.top || sortingOffset.top + windowScrollDelta.top + offset.height >= edgeOffset.top + height)) {
// If the current node is to the right on the same row, or below the node that's being dragged
// then move it to the left
translate.x = -(this.width + this.marginOffset.x);
if (edgeOffset.left + translate.x < this.containerBoundingRect.left + offset.width) {
// If it moves passed the left bounds, then animate it to the last position of the previous row.
// We just use the offset of the previous node to calculate where to move, because that node's original position
// is exactly where we want to go
translate.x = prevNode.edgeOffset.left - edgeOffset.left;
translate.y = prevNode.edgeOffset.top - edgeOffset.top;
}
this.newIndex = index;
}
} else {
if (index > this.index && sortingOffset.left + windowScrollDelta.left + offset.width >= edgeOffset.left) {
translate.x = -(this.width + this.marginOffset.x);
this.newIndex = index;
} else if (index < this.index && sortingOffset.left + windowScrollDelta.left <= edgeOffset.left + offset.width) {
translate.x = this.width + this.marginOffset.x;
if (this.newIndex == null) {
this.newIndex = index;
}
}
}
} else if (this.axis.y) {
if (index > this.index && sortingOffset.top + windowScrollDelta.top + offset.height >= edgeOffset.top) {
translate.y = -(this.height + this.marginOffset.y);
this.newIndex = index;
} else if (index < this.index && sortingOffset.top + windowScrollDelta.top <= edgeOffset.top + offset.height) {
translate.y = this.height + this.marginOffset.y;
if (this.newIndex == null) {
this.newIndex = index;
}
}
}
node.style[vendorPrefix + 'Transform'] = 'translate3d(' + translate.x + 'px,' + translate.y + 'px,0)';
}
if (this.newIndex == null) {
this.newIndex = this.index;
}
if (onSortOver && this.newIndex !== prevIndex) {
onSortOver({
newIndex: this.newIndex,
oldIndex: prevIndex,
index: this.index,
collection: this.manager.active.collection
});
}
}
}, {
key: 'getWrappedInstance',
value: function getWrappedInstance() {
invariant(config.withRef, 'To access the wrapped instance, you need to pass in {withRef: true} as the second argument of the SortableContainer() call');
return this.refs.wrappedInstance;
}
}, {
key: 'getContainer',
value: function getContainer() {
var getContainer = this.props.getContainer;
if (typeof getContainer !== 'function') {
return findDOMNode(this);
}
return getContainer(config.withRef ? this.getWrappedInstance() : undefined);
}
}, {
key: 'render',
value: function render() {
var ref = config.withRef ? 'wrappedInstance' : null;
return React.createElement(WrappedComponent, _extends({
ref: ref
}, omit(this.props, 'contentWindow', 'useWindowAsScrollContainer', 'distance', 'helperClass', 'hideSortableGhost', 'transitionDuration', 'useDragHandle', 'pressDelay', 'pressThreshold', 'shouldCancelStart', 'onSortStart', 'onSortMove', 'onSortEnd', 'axis', 'lockAxis', 'lockOffset', 'lockToContainerEdges', 'getContainer', 'getHelperDimensions')));
}
}]);
return _class;
}(Component), _class.displayName = provideDisplayName('sortableList', WrappedComponent), _class.defaultProps = {
axis: 'y',
transitionDuration: 300,
pressDelay: 0,
pressThreshold: 5,
distance: 0,
useWindowAsScrollContainer: false,
hideSortableGhost: true,
shouldCancelStart: function shouldCancelStart(e) {
// Cancel sorting if the event target is an `input`, `textarea`, `select` or `option`
var disabledElements = ['input', 'textarea', 'select', 'option', 'button'];
if (disabledElements.indexOf(e.target.tagName.toLowerCase()) !== -1) {
return true; // Return true to cancel sorting
}
},
lockToContainerEdges: false,
lockOffset: '50%',
getHelperDimensions: function getHelperDimensions(_ref) {
var node = _ref.node;
return {
width: node.offsetWidth,
height: node.offsetHeight
};
}
}, _class.propTypes = {
axis: PropTypes.oneOf(['x', 'y', 'xy']),
distance: PropTypes.number,
lockAxis: PropTypes.string,
helperClass: PropTypes.string,
transitionDuration: PropTypes.number,
contentWindow: PropTypes.any,
onSortStart: PropTypes.func,
onSortMove: PropTypes.func,
onSortOver: PropTypes.func,
onSortEnd: PropTypes.func,
shouldCancelStart: PropTypes.func,
pressDelay: PropTypes.number,
useDragHandle: PropTypes.bool,
useWindowAsScrollContainer: PropTypes.bool,
hideSortableGhost: PropTypes.bool,
lockToContainerEdges: PropTypes.bool,
lockOffset: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string]))]),
getContainer: PropTypes.func,
getHelperDimensions: PropTypes.func
}, _class.childContextTypes = {
manager: PropTypes.object.isRequired
}, _temp;
}
Example #25
Source File: index.js From Lynx with MIT License | 4 votes |
// Export Higher Order Sortable Element Component
export default function sortableElement(WrappedComponent) {
var _class, _temp;
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { withRef: false };
return _temp = _class = function (_Component) {
_inherits(_class, _Component);
function _class() {
_classCallCheck(this, _class);
return _possibleConstructorReturn(this, (_class.__proto__ || _Object$getPrototypeOf(_class)).apply(this, arguments));
}
_createClass(_class, [{
key: 'componentDidMount',
value: function componentDidMount() {
var _props = this.props,
collection = _props.collection,
disabled = _props.disabled,
index = _props.index;
if (!disabled) {
this.setDraggable(collection, index);
}
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
if (this.props.index !== nextProps.index && this.node) {
this.node.sortableInfo.index = nextProps.index;
}
if (this.props.disabled !== nextProps.disabled) {
var collection = nextProps.collection,
disabled = nextProps.disabled,
index = nextProps.index;
if (disabled) {
this.removeDraggable(collection);
} else {
this.setDraggable(collection, index);
}
} else if (this.props.collection !== nextProps.collection) {
this.removeDraggable(this.props.collection);
this.setDraggable(nextProps.collection, nextProps.index);
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
var _props2 = this.props,
collection = _props2.collection,
disabled = _props2.disabled;
if (!disabled) this.removeDraggable(collection);
}
}, {
key: 'setDraggable',
value: function setDraggable(collection, index) {
var node = this.node = findDOMNode(this);
node.sortableInfo = {
index: index,
collection: collection,
manager: this.context.manager
};
this.ref = { node: node };
this.context.manager.add(collection, this.ref);
}
}, {
key: 'removeDraggable',
value: function removeDraggable(collection) {
this.context.manager.remove(collection, this.ref);
}
}, {
key: 'getWrappedInstance',
value: function getWrappedInstance() {
invariant(config.withRef, 'To access the wrapped instance, you need to pass in {withRef: true} as the second argument of the SortableElement() call');
return this.refs.wrappedInstance;
}
}, {
key: 'render',
value: function render() {
var ref = config.withRef ? 'wrappedInstance' : null;
return React.createElement(WrappedComponent, _extends({
ref: ref
}, omit(this.props, 'collection', 'disabled', 'index')));
}
}]);
return _class;
}(Component), _class.displayName = provideDisplayName('sortableElement', WrappedComponent), _class.contextTypes = {
manager: PropTypes.object.isRequired
}, _class.propTypes = {
index: PropTypes.number.isRequired,
collection: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
disabled: PropTypes.bool
}, _class.defaultProps = {
collection: 0
}, _temp;
}
Example #26
Source File: Trigger.js From the-eye-knows-the-garbage with MIT License | 4 votes |
Trigger = function (_React$Component) {
_inherits(Trigger, _React$Component);
function Trigger() {
_classCallCheck(this, Trigger);
var _this = _possibleConstructorReturn(this, (Trigger.__proto__ || Object.getPrototypeOf(Trigger)).apply(this, arguments));
_this.onDocumentClick = function (event) {
if (_this.props.mask && !_this.props.maskClosable) {
return;
}
var target = event.target;
var root = findDOMNode(_this);
var popupNode = _this.getPopupDomNode();
if (!contains(root, target) && !contains(popupNode, target)) {
_this.close();
}
};
_this.getPopupAlign = function () {
var props = _this.props;
var popupPlacement = props.popupPlacement,
popupAlign = props.popupAlign,
builtinPlacements = props.builtinPlacements;
if (popupPlacement && builtinPlacements) {
return getAlignFromPlacement(builtinPlacements, popupPlacement, popupAlign);
}
return popupAlign;
};
_this.getRootDomNode = function () {
return findDOMNode(_this);
};
_this.getPopupClassNameFromAlign = function (align) {
var className = [];
var props = _this.props;
var popupPlacement = props.popupPlacement,
builtinPlacements = props.builtinPlacements,
prefixCls = props.prefixCls;
if (popupPlacement && builtinPlacements) {
className.push(getPopupClassNameFromAlign(builtinPlacements, prefixCls, align));
}
if (props.getPopupClassNameFromAlign) {
className.push(props.getPopupClassNameFromAlign(align));
}
return className.join(' ');
};
_this.close = function () {
if (_this.props.onClose) {
_this.props.onClose();
}
};
_this.onAnimateLeave = function () {
if (_this.props.destroyPopupOnHide) {
var container = _this._container;
if (container) {
ReactDOM.unmountComponentAtNode(container);
container.parentNode.removeChild(container);
}
}
};
_this.removeContainer = function () {
var container = document.querySelector('#' + _this.props.prefixCls + '-container');
if (container) {
ReactDOM.unmountComponentAtNode(container);
container.parentNode.removeChild(container);
}
};
return _this;
}
_createClass(Trigger, [{
key: 'componentDidMount',
value: function componentDidMount() {
if (this.props.visible) {
this.componentDidUpdate();
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
if (this.props.visible) {
if (!IS_REACT_16) {
this.renderDialog(false);
}
}
this.clearOutsideHandler();
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate() {
var _this2 = this;
if (!IS_REACT_16) {
this.renderDialog(this.props.visible);
}
if (this.props.visible) {
if (!this.touchOutsideHandler) {
this.touchOutsideHandler = setTimeout(function () {
var currentDocument = _this2.props.getDocument();
_this2.touchOutsideHandler = addEventListener(currentDocument, 'touchend', _this2.onDocumentClick);
});
}
return;
}
this.clearOutsideHandler();
}
}, {
key: 'clearOutsideHandler',
value: function clearOutsideHandler() {
if (this.touchOutsideHandler) {
if (this.touchOutsideHandler.remove) {
this.touchOutsideHandler.remove();
}
this.touchOutsideHandler = null;
}
}
}, {
key: 'getPopupDomNode',
value: function getPopupDomNode() {
if (this._component && this._component.getPopupDomNode) {
return this._component.getPopupDomNode();
}
return null;
}
}, {
key: 'saveRef',
value: function saveRef(el, visible) {
this.popupRef = el;
this._component = el;
this.props.afterPopupVisibleChange(visible);
}
}, {
key: 'getComponent',
value: function getComponent(visible) {
var _this3 = this;
var props = _extends({}, this.props);
['visible', 'onAnimateLeave'].forEach(function (key) {
if (props.hasOwnProperty(key)) {
delete props[key];
}
});
return React.createElement(
Popup,
{ key: 'popup', ref: function ref(el) {
return _this3.saveRef(el, visible);
}, prefixCls: props.prefixCls, destroyPopupOnHide: props.destroyPopupOnHide, visible: visible, className: props.popupClassName, align: this.getPopupAlign(), onAlign: props.onPopupAlign, animation: props.popupAnimation, getClassNameFromAlign: this.getPopupClassNameFromAlign, getRootDomNode: this.getRootDomNode, style: props.popupStyle, mask: props.mask, zIndex: props.zIndex, transitionName: props.popupTransitionName, maskAnimation: props.maskAnimation, maskTransitionName: props.maskTransitionName, onAnimateLeave: this.onAnimateLeave },
typeof props.popup === 'function' ? props.popup() : props.popup
);
}
}, {
key: 'getContainer',
value: function getContainer() {
if (!this._container) {
var props = this.props;
var popupContainer = document.createElement('div');
popupContainer.style.position = 'absolute';
popupContainer.style.top = '0';
popupContainer.style.left = '0';
popupContainer.style.width = '100%';
var mountNode = props.getPopupContainer ? props.getPopupContainer(findDOMNode(this)) : props.getDocument().body;
mountNode.appendChild(popupContainer);
this._container = popupContainer;
}
return this._container;
}
}, {
key: 'renderDialog',
value: function renderDialog(visible) {
ReactDOM.unstable_renderSubtreeIntoContainer(this, this.getComponent(visible), this.getContainer());
}
}, {
key: 'render',
value: function render() {
var props = this.props;
var children = props.children;
var child = React.Children.only(children);
var newChildProps = {
onClick: this.props.onTargetClick,
key: 'trigger'
};
var trigger = React.cloneElement(child, newChildProps);
if (!IS_REACT_16) {
return trigger;
}
var portal = void 0;
if (props.visible || this._component) {
portal = ReactDOM.createPortal(this.getComponent(props.visible), this.getContainer());
}
return [trigger, portal];
}
}]);
return Trigger;
}(React.Component)
Example #27
Source File: index.jsx From prometheusPro with MIT License | 4 votes |
render() {
const {
listAndbasicList: { list },
loading,
} = this.props;
const {
form: { getFieldDecorator },
} = this.props;
const { visible, done, current = {} } = this.state;
const editAndDelete = (key, currentItem) => {
if (key === 'edit') this.showEditModal(currentItem);
else if (key === 'delete') {
Modal.confirm({
title: '删除任务',
content: '确定删除该任务吗?',
okText: '确认',
cancelText: '取消',
onOk: () => this.deleteItem(currentItem.id),
});
}
};
const modalFooter = done
? {
footer: null,
onCancel: this.handleDone,
}
: {
okText: '保存',
onOk: this.handleSubmit,
onCancel: this.handleCancel,
};
const Info = ({ title, value, bordered }) => (
<div className={styles.headerInfo}>
<span>{title}</span>
<p>{value}</p>
{bordered && <em />}
</div>
);
const extraContent = (
<div className={styles.extraContent}>
<RadioGroup defaultValue="all">
<RadioButton value="all">全部</RadioButton>
<RadioButton value="progress">进行中</RadioButton>
<RadioButton value="waiting">等待中</RadioButton>
</RadioGroup>
<Search className={styles.extraContentSearch} placeholder="请输入" onSearch={() => ({})} />
</div>
);
const paginationProps = {
showSizeChanger: true,
showQuickJumper: true,
pageSize: 5,
total: 50,
};
const ListContent = ({ data: { owner, createdAt, percent, status } }) => (
<div className={styles.listContent}>
<div className={styles.listContentItem}>
<span>Owner</span>
<p>{owner}</p>
</div>
<div className={styles.listContentItem}>
<span>开始时间</span>
<p>{moment(createdAt).format('YYYY-MM-DD HH:mm')}</p>
</div>
<div className={styles.listContentItem}>
<Progress
percent={percent}
status={status}
strokeWidth={6}
style={{
width: 180,
}}
/>
</div>
</div>
);
const MoreBtn = ({ item }) => (
<Dropdown
overlay={
<Menu onClick={({ key }) => editAndDelete(key, item)}>
<Menu.Item key="edit">编辑</Menu.Item>
<Menu.Item key="delete">删除</Menu.Item>
</Menu>
}
>
<a>
更多 <DownOutlined />
</a>
</Dropdown>
);
const getModalContent = () => {
if (done) {
return (
<Result
status="success"
title="操作成功"
subTitle="一系列的信息描述,很短同样也可以带标点。"
extra={
<Button type="primary" onClick={this.handleDone}>
知道了
</Button>
}
className={styles.formResult}
/>
);
}
return (
<Form onSubmit={this.handleSubmit}>
<FormItem label="任务名称" {...this.formLayout}>
{getFieldDecorator('title', {
rules: [
{
required: true,
message: '请输入任务名称',
},
],
initialValue: current.title,
})(<Input placeholder="请输入" />)}
</FormItem>
<FormItem label="开始时间" {...this.formLayout}>
{getFieldDecorator('createdAt', {
rules: [
{
required: true,
message: '请选择开始时间',
},
],
initialValue: current.createdAt ? moment(current.createdAt) : null,
})(
<DatePicker
showTime
placeholder="请选择"
format="YYYY-MM-DD HH:mm:ss"
style={{
width: '100%',
}}
/>,
)}
</FormItem>
<FormItem label="任务负责人" {...this.formLayout}>
{getFieldDecorator('owner', {
rules: [
{
required: true,
message: '请选择任务负责人',
},
],
initialValue: current.owner,
})(
<Select placeholder="请选择">
<SelectOption value="付晓晓">付晓晓</SelectOption>
<SelectOption value="周毛毛">周毛毛</SelectOption>
</Select>,
)}
</FormItem>
<FormItem {...this.formLayout} label="产品描述">
{getFieldDecorator('subDescription', {
rules: [
{
message: '请输入至少五个字符的产品描述!',
min: 5,
},
],
initialValue: current.subDescription,
})(<TextArea rows={4} placeholder="请输入至少五个字符" />)}
</FormItem>
</Form>
);
};
return (
<>
<PageHeaderWrapper>
<div className={styles.standardList}>
<Card bordered={false}>
<Row>
<Col sm={8} xs={24}>
<Info title="我的待办" value="8个任务" bordered />
</Col>
<Col sm={8} xs={24}>
<Info title="本周任务平均处理时间" value="32分钟" bordered />
</Col>
<Col sm={8} xs={24}>
<Info title="本周完成任务数" value="24个任务" />
</Col>
</Row>
</Card>
<Card
className={styles.listCard}
bordered={false}
title="基本列表"
style={{
marginTop: 24,
}}
bodyStyle={{
padding: '0 32px 40px 32px',
}}
extra={extraContent}
>
<Button
type="dashed"
style={{
width: '100%',
marginBottom: 8,
}}
onClick={this.showModal}
ref={component => {
// eslint-disable-next-line react/no-find-dom-node
this.addBtn = findDOMNode(component);
}}
>
<PlusOutlined />
添加
</Button>
<List
size="large"
rowKey="id"
loading={loading}
pagination={paginationProps}
dataSource={list}
renderItem={item => (
<List.Item
actions={[
<a
key="edit"
onClick={e => {
e.preventDefault();
this.showEditModal(item);
}}
>
编辑
</a>,
<MoreBtn key="more" item={item} />,
]}
>
<List.Item.Meta
avatar={<Avatar src={item.logo} shape="square" size="large" />}
title={<a href={item.href}>{item.title}</a>}
description={item.subDescription}
/>
<ListContent data={item} />
</List.Item>
)}
/>
</Card>
</div>
</PageHeaderWrapper>
<Modal
title={done ? null : `任务${current ? '编辑' : '添加'}`}
className={styles.standardListForm}
width={640}
bodyStyle={
done
? {
padding: '72px 0',
}
: {
padding: '28px 0 0',
}
}
destroyOnClose
visible={visible}
{...modalFooter}
>
{getModalContent()}
</Modal>
</>
);
}
Example #28
Source File: wave.js From the-eye-knows-the-garbage with MIT License | 4 votes |
Wave = /*#__PURE__*/function (_React$Component) {
_inherits(Wave, _React$Component);
var _super = _createSuper(Wave);
function Wave() {
var _this;
_classCallCheck(this, Wave);
_this = _super.apply(this, arguments);
_this.animationStart = false;
_this.destroyed = false;
_this.onClick = function (node, waveColor) {
if (!node || isHidden(node) || node.className.indexOf('-leave') >= 0) {
return;
}
var insertExtraNode = _this.props.insertExtraNode;
_this.extraNode = document.createElement('div');
var _assertThisInitialize = _assertThisInitialized(_this),
extraNode = _assertThisInitialize.extraNode;
var getPrefixCls = _this.context.getPrefixCls;
extraNode.className = "".concat(getPrefixCls(''), "-click-animating-node");
var attributeName = _this.getAttributeName();
node.setAttribute(attributeName, 'true'); // Not white or transparnt or grey
styleForPesudo = styleForPesudo || document.createElement('style');
if (waveColor && waveColor !== '#ffffff' && waveColor !== 'rgb(255, 255, 255)' && isNotGrey(waveColor) && !/rgba\((?:\d*, ){3}0\)/.test(waveColor) && // any transparent rgba color
waveColor !== 'transparent') {
// Add nonce if CSP exist
if (_this.csp && _this.csp.nonce) {
styleForPesudo.nonce = _this.csp.nonce;
}
extraNode.style.borderColor = waveColor;
styleForPesudo.innerHTML = "\n [".concat(getPrefixCls(''), "-click-animating-without-extra-node='true']::after, .").concat(getPrefixCls(''), "-click-animating-node {\n --antd-wave-shadow-color: ").concat(waveColor, ";\n }");
if (!document.body.contains(styleForPesudo)) {
document.body.appendChild(styleForPesudo);
}
}
if (insertExtraNode) {
node.appendChild(extraNode);
}
TransitionEvents.addStartEventListener(node, _this.onTransitionStart);
TransitionEvents.addEndEventListener(node, _this.onTransitionEnd);
};
_this.onTransitionStart = function (e) {
if (_this.destroyed) {
return;
}
var node = findDOMNode(_assertThisInitialized(_this));
if (!e || e.target !== node || _this.animationStart) {
return;
}
_this.resetEffect(node);
};
_this.onTransitionEnd = function (e) {
if (!e || e.animationName !== 'fadeEffect') {
return;
}
_this.resetEffect(e.target);
};
_this.bindAnimationEvent = function (node) {
if (!node || !node.getAttribute || node.getAttribute('disabled') || node.className.indexOf('disabled') >= 0) {
return;
}
var onClick = function onClick(e) {
// Fix radio button click twice
if (e.target.tagName === 'INPUT' || isHidden(e.target)) {
return;
}
_this.resetEffect(node); // Get wave color from target
var waveColor = getComputedStyle(node).getPropertyValue('border-top-color') || // Firefox Compatible
getComputedStyle(node).getPropertyValue('border-color') || getComputedStyle(node).getPropertyValue('background-color');
_this.clickWaveTimeoutId = window.setTimeout(function () {
return _this.onClick(node, waveColor);
}, 0);
raf.cancel(_this.animationStartId);
_this.animationStart = true; // Render to trigger transition event cost 3 frames. Let's delay 10 frames to reset this.
_this.animationStartId = raf(function () {
_this.animationStart = false;
}, 10);
};
node.addEventListener('click', onClick, true);
return {
cancel: function cancel() {
node.removeEventListener('click', onClick, true);
}
};
};
_this.renderWave = function (_ref) {
var csp = _ref.csp;
var children = _this.props.children;
_this.csp = csp;
return children;
};
return _this;
}
_createClass(Wave, [{
key: "componentDidMount",
value: function componentDidMount() {
var node = findDOMNode(this);
if (!node || node.nodeType !== 1) {
return;
}
this.instance = this.bindAnimationEvent(node);
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
if (this.instance) {
this.instance.cancel();
}
if (this.clickWaveTimeoutId) {
clearTimeout(this.clickWaveTimeoutId);
}
this.destroyed = true;
}
}, {
key: "getAttributeName",
value: function getAttributeName() {
var getPrefixCls = this.context.getPrefixCls;
var insertExtraNode = this.props.insertExtraNode;
return insertExtraNode ? "".concat(getPrefixCls(''), "-click-animating") : "".concat(getPrefixCls(''), "-click-animating-without-extra-node");
}
}, {
key: "resetEffect",
value: function resetEffect(node) {
if (!node || node === this.extraNode || !(node instanceof Element)) {
return;
}
var insertExtraNode = this.props.insertExtraNode;
var attributeName = this.getAttributeName();
node.setAttribute(attributeName, 'false'); // edge has bug on `removeAttribute` #14466
if (styleForPesudo) {
styleForPesudo.innerHTML = '';
}
if (insertExtraNode && this.extraNode && node.contains(this.extraNode)) {
node.removeChild(this.extraNode);
}
TransitionEvents.removeStartEventListener(node, this.onTransitionStart);
TransitionEvents.removeEndEventListener(node, this.onTransitionEnd);
}
}, {
key: "render",
value: function render() {
return /*#__PURE__*/React.createElement(ConfigConsumer, null, this.renderWave);
}
}]);
return Wave;
}(React.Component)
Example #29
Source File: MediaPlayer.js From Full-Stack-React-Projects-Second-Edition with MIT License | 4 votes |
export default function MediaPlayer(props) {
const classes = useStyles()
const [playing, setPlaying] = useState(false)
const [volume, setVolume] = useState(0.8)
const [muted, setMuted] = useState(false)
const [duration, setDuration] = useState(0)
const [seeking, setSeeking] = useState(false)
const [playbackRate, setPlaybackRate] = useState(1.0)
const [loop, setLoop] = useState(false)
const [fullscreen, setFullscreen] = useState(false)
const [videoError, setVideoError] = useState(false)
let playerRef = useRef(null)
const [values, setValues] = useState({
played: 0, loaded: 0, ended: false
})
useEffect(() => {
if (screenfull.enabled) {
screenfull.on('change', () => {
let fullscreen = screenfull.isFullscreen ? true : false
setFullscreen(fullscreen)
})
}
}, [])
useEffect(() => {
setVideoError(false)
}, [props.srcUrl])
const changeVolume = e => {
setVolume(parseFloat(e.target.value))
}
const toggleMuted = () => {
setMuted(!muted)
}
const playPause = () => {
setPlaying(!playing)
}
const onLoop = () => {
setLoop(!loop)
}
const onProgress = progress => {
// We only want to update time slider if we are not currently seeking
if (!seeking) {
setValues({...values, played:progress.played, loaded: progress.loaded})
}
}
const onClickFullscreen = () => {
screenfull.request(findDOMNode(playerRef))
}
const onEnded = () => {
if(loop){
setPlaying(true)
} else{
props.handleAutoplay(()=>{
setValues({...values, ended:true})
setPlaying(false)
})
}
}
const onDuration = (duration) => {
setDuration(duration)
}
const onSeekMouseDown = e => {
setSeeking(true)
}
const onSeekChange = e => {
setValues({...values, played:parseFloat(e.target.value), ended: parseFloat(e.target.value) >= 1})
}
const onSeekMouseUp = e => {
setSeeking(false)
playerRef.seekTo(parseFloat(e.target.value))
}
const ref = player => {
playerRef = player
}
const format = (seconds) => {
const date = new Date(seconds * 1000)
const hh = date.getUTCHours()
let mm = date.getUTCMinutes()
const ss = ('0' + date.getUTCSeconds()).slice(-2)
if (hh) {
mm = ('0' + date.getUTCMinutes()).slice(-2)
return `${hh}:${mm}:${ss}`
}
return `${mm}:${ss}`
}
const showVideoError = e => {
console.log(e)
setVideoError(true)
}
return (<div>
{videoError && <p className={classes.videoError}>Video Error. Try again later.</p>}
<div className={classes.flex}>
<ReactPlayer
ref={ref}
width={fullscreen ? '100%':'inherit'}
height={fullscreen ? '100%':'inherit'}
style={fullscreen ? {position:'relative'} : {maxHeight: '500px'}}
config={{ attributes: { style: { height: '100%', width: '100%'} } }}
url={props.srcUrl}
playing={playing}
loop={loop}
playbackRate={playbackRate}
volume={volume}
muted={muted}
onEnded={onEnded}
onError={showVideoError}
onProgress={onProgress}
onDuration={onDuration}/>
<br/>
</div>
<div className={classes.controls}>
<LinearProgress color="primary" variant="buffer" value={values.played*100} valueBuffer={values.loaded*100} style={{width: '100%'}} classes={{
colorPrimary: classes.primaryColor,
dashedColorPrimary : classes.primaryDashed,
dashed: classes.dashed
}}/>
<input type="range" min={0} max={1}
value={values.played} step='any'
onMouseDown={onSeekMouseDown}
onChange={onSeekChange}
onMouseUp={onSeekMouseUp}
className={classes.rangeRoot}/>
<IconButton color="primary" onClick={playPause}>
<Icon>{playing ? 'pause': (values.ended ? 'replay' : 'play_arrow')}</Icon>
</IconButton>
<IconButton disabled={!props.nextUrl} color="primary">
<Link to={props.nextUrl} style={{color: 'inherit'}}>
<Icon>skip_next</Icon>
</Link>
</IconButton>
<IconButton color="primary" onClick={toggleMuted}>
<Icon>{volume > 0 && !muted && 'volume_up' || muted && 'volume_off' || volume==0 && 'volume_mute'}</Icon>
</IconButton>
<input type="range" min={0} max={1} step='any' value={muted? 0 : volume} onChange={changeVolume} style={{verticalAlign: 'middle'}}/>
<IconButton color={loop? 'primary' : 'default'} onClick={onLoop}>
<Icon>loop</Icon>
</IconButton>
<IconButton color="primary" onClick={onClickFullscreen}>
<Icon>fullscreen</Icon>
</IconButton>
<span style={{float: 'right', padding: '10px', color: '#b83423'}}>
<time dateTime={`P${Math.round(duration * values.played)}S`}>
{format(duration * values.played)}
</time> / <time dateTime={`P${Math.round(duration)}S`}>
{format(duration)}
</time>
</span>
</div>
</div>
)
}