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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
// 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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
_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 vote down vote up
// 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 vote down vote up
// 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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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>
  )
}