react-component / trigger Goto Github PK
View Code? Open in Web Editor NEWAbstract React Trigger
Home Page: http://react-component.github.io/trigger/
License: MIT License
Abstract React Trigger
Home Page: http://react-component.github.io/trigger/
License: MIT License
Expected result: When you hide a popup, you need an animation of type 'fade'
What is: Popup disappeared before the animation
Possible solution: install setTimeout when calling onPopupVisibleChange
<Trigger
...
popupVisible={visible}
onPopupVisibleChange={this.onVisibleChange}
popupTransitionName="fade"
On rc-animate, transitionName can receive String and Object.
https://github.com/react-component/animate#props
On rc-trigger, it works fine when I pass Object for transitionName.
But "invalid prop" warning was shown in my console.
PropTypes should be fixed to
popupTransitionName: PropTypes.oneOfType[PropTypes.string, PropTypes.object],
Line 41 in a12dd91
点击 mask 时可以在 onPopupVisibleChange
回调里用参数标记出来、表示此时点击的是 mask 层,使用者自己控制是否 visible
This component is very configurable, I like it. I miss a small additional functionality, what you think about it?:
Only one Popup visible at once even if you use the mouseLeaveDelay/blurDelay option. I have a special use case where you can hover over a bunch of tokens list. When your drag your mouse over a lot of tokens first before reach your target token and use the delay options, you have a lot of popups open at once before they disapper. A solution is to listen to a global 'popup-reset' event on the window object.
edit:
I made a quick wrapper arround the trigger component to show what I mean:
export default React.createClass({
componentDidMount: function() {
window.addEventListener('popup-visible', this.onWindowPopupVisible, false);
},
onWindowPopupVisible: function(event) {
if (this.refs != null && this != event.detail.component) {
return this.refs.baseTrigger.setState({
popupVisible: false
});
}
},
componentWillUnmount: function() {
window.removeEventListener('popup-visible', this.onWindowPopupVisible);
},
afterPopupVisibleChange: function(visible) {
if (visible) {
window.dispatchEvent(new CustomEvent('popup-visible', {detail: {component: this}}));
}
},
render: function() {
return (
<BaseTrigger {...this.props}
builtinPlacements={builtinPlacements}
ref="baseTrigger"
afterPopupVisibleChange={this.afterPopupVisibleChange} />
);
}
});
I don't know exactly if this have something to do with the previous issue: #11
The problem is that when you use component's which render outside of the trigger popup component (best example is the rc-dropdown component) any event which is fired on this content (onClick, mouseLeave) will propagated to the onDocumentClick event which execute the code which close the popup after the configured time or instantly (in the case when clicking an item in the dropdown menu).
So my idea is to add an additional property to the trigger component (called something like includedPopupSelector). Which will be checked in the triggers onDocumentClick and onLeave event too (with the same logic likes jQueries closest method https://api.jquery.com/closest/#closest1)
Otherwise every other component which is based on rc-trigger and render something outside the popup can't be used.
Have you guys a better idea how to solve this cases?
1.7.x start to use getContainerRenderMixin, however in a wrong way.
from https://github.com/react-component/util/blob/master/src/getContainerRenderMixin.jsx#L20, we can see renderComponent receive two params: componentArg
& ready
. In fact, componentArg
is useless in trigger, because getComponent don't receive it.
But Trigger pass the ready callback as the first param which make the ready callback will never be triggered. https://github.com/react-component/trigger/blob/master/src/Trigger.jsx#L166
Behaviour:
When using rc-trigger (eg. via Ant Design's Dropdown
) with a click
type of trigger, the popup will not be closed if a user clicks or taps on an iframe in the page.
Expected Behaviour:
When a user clicks or taps anywhere on the document or an iframe within the document, the popup will be closed. This works fine for contextMenu
types of triggers.
Steps to Reproduce:
(Using Ant Design Dropdown)
trigger={['click']}
) and an iframe that takes up a large part of the screenI have submitted a PR to help with fixing this #96
我想将弹出对象 相对于其他元素align
#90
I need to set z-index of popup containers but it is difficult because they doesn't have className attribute.
github图片抽风,点进去外链看即可
如上图,Modal 弹层里面有一个 Trigger,body 的高度很大,Popup 就会有一部分展现不出来,debug了一下代码,发现跟 dom-align 有关,domAlign 函数计算可显示区域的尺寸有问题,忽略了 body 为 overflow: hidden 的场景
现在移动到tooltip的展示层上是不会自动消失的。
我们需要的是,移动到图片上弹出个说明,但仅仅是说明而已,不想移动到tooltip之后还能在上面复制东西,只想鼠标离开图片后,tooltip消失,无论鼠标移到哪。
目前 mouseEnterDelay={0}
时,鼠标快速移动仍然能移到浮层上。
Just like title states. By updating rc-util to 4.x you have introduced duplicate rc-util dependency, so now both versions are included in bundles.
How about just remove rc-util from dependencies completely and just rely on transitive rc-util dep coming from rc-align?
Older versions of rc-animate
and rc-align
don't work in react 16, and when I install rc-trigger
for some reason yarn
selects those older versions for installation unless I add resolutions to override it.
The dependencies should be updated to require a version of those libraries that work in react 16 now that this library requires react 16.
getContainerRenderMixin.js Uncaught TypeError: getComponent is not a function
项目中需要要改到源码,麻烦告知一下为什么同一个1.10.4版本,为什么会不一样
I am having a weird behavior where the renderPopup method passed to unstable_renderSubtreeIntoContainer
has the wrong context. this
instead of referring to a react component instead is TopLevelWrapper
. This causes this.isMounted()
to throw and error wrecking things.
Here is the line im referring too, https://github.com/react-component/trigger/blob/master/src/Trigger.jsx#L83
Any ideas on what might be happing? I am upgrading from an earlier version of the Tooltip component
I should mention if I just guard against this by doing this.isMounted && this.isMounted()
everything works as expected.
If I want to use it as a validation message feedback, how can I trigger show and hide via code?
Hey,
I have a problem that on the first click/hover my popup aligns incorrectly, and on the second time it jumps on the correct place. The popup has long text inside and the text goes on two lines so that it fits in the window. With short texts the popup aligns correctly but if the window is scaled small and the text inside popup is even few words too long the jumping starts again.
I downloaded your project, added some long text on your simple example and got the same problem. So you can try that out aswell to see the issue. Do you have any idea where the misalignment might come from? I haven't found it yet.
I'm using ant-design which utilises rc-dropdown
. I get the following error for the type of rc-trigger
, when rc-dropdown
tries to create a React element of rc-trigger
.
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the render method of `Dropdown`.
in Dropdown (created by Dropdown)
in Dropdown (created by DashboardTemplate)
where the first dropdown is an rc-dropdown
element, and the second one the dropdown element from antd
.
The code in rc-dropdown
which yields the error:
return _react2["default"].createElement(
_rcTrigger2["default"],
_extends({}, otherProps, {
prefixCls: prefixCls,
ref: 'trigger',
popupClassName: overlayClassName,
popupStyle: overlayStyle,
builtinPlacements: _placements2["default"],
action: trigger,
showAction: showAction,
hideAction: hideAction,
popupPlacement: placement,
popupAlign: align,
popupTransitionName: transitionName,
popupAnimation: animation,
popupVisible: this.state.visible,
afterPopupVisibleChange: this.afterVisibleChange,
popup: this.getMenuElement(),
onPopupVisibleChange: this.onVisibleChange,
getPopupContainer: getPopupContainer
}),
children
);
_rcTrigger2
is defined as follows:
var _rcTrigger = require('rc-trigger');
var _rcTrigger2 = _interopRequireDefault(_rcTrigger);
I'm not totally sure whether it's a problem with rc-trigger
, rc-dropdown
, ant-design or e.g. Babel, but it is probably since the switch to ES code.
Any ideas?
Hi,
Is it possible we can hide context menu by adding scrolling event on root component or his parent instead of only document?
Similar with contextMenuOutsideHandler1, can it handle not only document but also dom node we passed?
Thank you.
please show some demo that how the porps: getDocument to use? thanks
场景是单击下拉框(trigger包装),展示下拉列表(单击下拉列表收回下拉列表),单击某项出现模态窗,然后单击任何地方,下拉框收回,理想的效果是触发模态窗的逻辑,因为先触犯trigger绑定的mousedown引起的,如何避免这种情况的发生?
Hey, react 15.0.2 now warns about uknown props being passed to a DOM elements.
Warning: Unknown prop `visible` on <div> tag. Remove this prop from the element. For details, see https://fb.me/react-unknown-prop
in div (created by LazyRenderBox)
in LazyRenderBox (created by PopupInner)
in div (created by PopupInner)
in PopupInner (created by Popup)
in Align (created by Popup)
in AnimateChild (created by Animate)
in Animate (created by Popup)
in div (created by Popup)
in Popup
If Popup has placement with overflow options, it changes className once to overflown, but does'nt switch back if overflownot needed.
E.G. : We have rc-select dropdown menu with 'bottomLeft' placement. If there is no place on screen popup className would be set to topLeft.
In onAlign function you only check if alignClassName !== currentAlignClassName
, but I guess, you should also check if this.currentAlignClassName !== currentAlignClassName
onAlign = (popupDomNode, align) => {
const props = this.props;
const alignClassName = props.getClassNameFromAlign(props.align);
const currentAlignClassName = props.getClassNameFromAlign(align);
if (alignClassName !== currentAlignClassName) {
this.currentAlignClassName = currentAlignClassName;
popupDomNode.className = this.getClassName(currentAlignClassName);
}
props.onAlign(popupDomNode, align);
}
当使用antd组件(比如select组件)打包出来时再次使用的时候会抛出
getDefaultProps is only used on classic React.createClass definitions. Use a static property named
defaultProps instead
这个警告
原因是在rc-trigger组件使用了老版本的create-react-class版本 ,创建出来的component 的getDefaultProps有个属性isReactClassApproved 为undefined ,react的这个方法validatePropTypes会检查抛出这个错误
onPopupVisibleChange(popupVisible) {
this.setState({ popupVisible })
}
<Trigger
action={['click']}
popup={this.renderMenu('inline')}
popupAlign={{
points: ['tl', 'bl'],
offset: [0, 3]
}}
popupVisible={this.state.popupVisible}
onPopupVisibleChange={::this.onPopupVisibleChange}
mask
destroyPopupOnHide
>
<div className="mobile-trigger">
<Icon type="bars"/>
</div>
</Trigger>
里面的 mobile-trigger 点击后展开菜单。然后再点击后应该关闭的。但是却重复触发了事件,导致关闭后立刻打开了。
感觉像是点击穿透问题, fastclick 也用了,也无效。
document.addEventListener('DOMContentLoaded', () => FastClick.attach(document.body), false)
在这个 commit 中,click 事件替代了 mousedown 事件,但是会引发一些问题,click 事件相对 mousedown 的事件响应顺序相对靠后,当在业务组件中通过点击 button-example(监听的是 click 事件)操作来更新了组件内容,在更新时如果 unmount 了一些内容且包含了 button-example,那么在 onDoumentClick 中判断是否执行的时候将会误伤,因为 document 的 click 事件监听触发时机较晚,button-example 可能已经不在容器中了。
感觉这种情况有点极端,我的使用场景是popover中点击按钮之后,需要更新popover中的内容。
"rc-trigger": "2.6.2"
"react": "^16.4.2"
But when I change rc-trigger version to ^2.4.2, it works :) .
weird
Using rc-select.
This is due to latest version change, but I can't figure out why you have green test on your last commit while it obviously doesn't pass.
https://github.com/react-component/trigger/blob/master/src/Trigger.jsx#L108
it seems unstable_renderSubtreeIntoContainer will tirgger it's callback before returning a component instance.
https://github.com/facebook/react/blob/d2ff462b79937ec3016dcba81d91d93a4a015c78/src/renderers/dom/client/ReactMount.js#L399
in Trigger, it will call props.afterPopupVisibleChange in the callback, and then dropdown's afterPopupVisibleChange will try to get the popupDomNode of trigger which is not returned and then cause an error.
when using the getTooltipContainer
property, the unmountComponentAtNode call seems to unmount the tooltipContainer but afterwards tries to re-grab it using findDomNode here and call removeChild
on mountNode
. Unfortunately mountNode is now null at this point, causing the unmounting to fail and break the page. One easy fix would be to do:
if (mountNode) {
mountNode.removeChild(popupContainer);
}
Hi,
triggering a popup doesn't seem to work when the Trigger
's child is a React component.
So this works fine:
import React, { Component } from 'react'
import Trigger from 'rc-trigger'
export default class MyPage extends Component {
render () {
return <Trigger
action={['hover']}
popup={<span>popup</span>}
popupAlign={{
points: ['tl', 'bl'],
offset: [0, 3]
}}
>
<span>This is my span</span>
</Trigger>
}
}
But this doesn't work (the "popup" message does not show when hovering MyComponent
):
import React, { Component } from 'react'
import Trigger from 'rc-trigger'
class MyComponent extends Component {
render () {
return <span>This is my component</span>
}
}
export default class MyPage extends Component {
render () {
return <Trigger
action={['hover']}
popup={<span>popup</span>}
popupAlign={{
points: ['tl', 'bl'],
offset: [0, 3]
}}
>
<MyComponent />
</Trigger>
}
}
Is there a way I can make it work without wrapping the child with a span?
Thanks.
We upgraded from version 1.8.2 to 1.8.3 and found out that it isn't possible to interact with elements that are close to rc-trigger component anymore. I hope this screenshot explains more:
It seems that 2e4adf7 has caused this problem.
Hi,
are there any plans for updating the react version from 16.0 to 16.4?
We are using React.StrictMode and we encounter the following warning in the console:
"""
index.js:1427 Warning: Unsafe lifecycle methods were found within a strict-mode tree:
in div (created by MyReactComponent)
in MyReactComponent (created by component)
in div (created by component)
in component (created by RouterContext)
in RouterContext (created by Router)
in Router
componentWillMount: Please update the following components to use componentDidMount instead: Trigger
componentWillReceiveProps: Please update the following components to use static getDerivedStateFromProps instead: Trigger
Learn more about this warning here:
https://fb.me/react-strict-mode-warnings
"""
I know it's probably a lot a work to go around the code base and update all the older and now unsafe life-cycle methods, but I am just wondering if you have any plans on an update.
The popup does not stay open on Edge/Windows 10 when using touch. In the video both "hover" and "click" is checked, but the problem can be seen with only "hover".
Works fine on Chrome and Firefox.
IMG_4238.MOV.zip (Tooltip)
IMG_4245.MOV.zip (Trigger)
I am using rc-slider and I need to set the z-index for the element created by getContainer.
I also propose putting this logic inside componentDidMount() and clean up in componentWillUnmount.
Alternatively you could set the styling for the element within the portal. Right now it's a bit tricky to work with.
getContainer = () => {
const { props } = this;
const 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%';
const mountNode = props.getPopupContainer ?
props.getPopupContainer(findDOMNode(this)) : props.getDocument().body;
mountNode.appendChild(popupContainer);
return popupContainer;
}
isMounted is deprecated: https://github.com/facebook/react/blob/15-stable/src/isomorphic/modern/class/ReactComponent.js#L111
../react-component/trigger/src/Trigger.jsx: if (this.isMounted()) {
This line uses a method that doesn't work when components are constructed as ES6 classes. I believe the problem I am having is just a scope issue. The references to this
should really be references to self
.
https://github.com/react-component/trigger/blob/master/src/Trigger.jsx#L83
Getting errors about createPortal
not being defined for react 15
I think this import is the culprit:
Line 3 in 6e3c437
Probably needs to be conditionally loaded instead?
Hey, thank you for the ant-design. It save me lots of time.
I have a problem when use Dropdown. I want do some check in child onClick event. if not valid, I want to stop show the dropdown. But event.stopPropagation() doesn't work. should the onClick check the event is propagation stopped? And I don't find any other way to stop show dropdown.
Due to this issue: ant-design/ant-design#10325, I suggest that we add className
as a prop of Trigger
for convenience.
const props = this.props;
const children = props.children;
const child = React.Children.only(children);
const newChildProps = { key: 'trigger' };
// Merge some event handlers into `newChildProps`
const trigger = React.cloneElement(child, newChildProps);
import classNames from 'classnames';
// ...
const props = this.props;
const children = props.children;
const child = React.Children.only(children);
const newChildProps = {
key: 'trigger',
className: classNames(props.className, child.props.className),
};
// Merge some event handlers into `newChildProps`
const trigger = React.cloneElement(child, newChildProps);
name | type | default | description |
---|---|---|---|
className | string | additional className added to trigger |
@yesmeck Shall I create a PR directly? Thanks.
Issue in fact in css-animate
. follow react-component/animate#30
Can add .d.ts file for rc-trigger?
Triggers cascaded, how to stop one of the trigger mouse down event propagation.
I handle it by stopImmediatePropagation
now, but when nested more, is not convenient do that one by one.
Is there any interface to do that conveniently?
Is there possible to support?
I was wondering if this module works fine with react 16. As anyone tried?
Online demo: http://codepen.io/anon/pen/peovPZ?editors=0110
When popup node is inserted to body at first time, it will make scrollbar appearing. And the scrollbar affect the position of trigger.
mixins: [
getContainerRenderMixin({
autoMount: false,
isVisible(instance) {
return instance.state.popupVisible;
},
getContainer(instance) {
const popupContainer = document.createElement('div');
const mountNode = instance.props.getPopupContainer ?
instance.props.getPopupContainer(findDOMNode(instance)) : document.body;
mountNode.appendChild(popupContainer);
return popupContainer;
},
}),
],
In a project I am working on, I am using preact
and preact-compat
instead of React. It looks like when I do the following:
<Tooltip overlay={overlay}>
<button onClick={this.handleClick}></button>
</Tooltip>
I get the following error:
Uncaught (in promise) TypeError: Cannot read property 'onClick' of undefined
The following code snippet in rc-tooltip
appears to be the culprit:
createTwoChains: function createTwoChains(event) {
var childPros = this.props.children.props;
var props = this.props;
if (childPros[event] && props[event]) {
return this['fire' + event];
}
return childPros[event] || props[event];
}
In Preact, this.props.children
returns an array even though I am only passing one child element.
Under 'lib' folder, all js file contains:
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
But in 1.2.0:
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
'default' is a keyword in ie8, which will report a error in 1.2.1
I have a website where I am using Ant Design a lot and there are a few pages where so many popups and tooltips are used. Some of them are static text, some are dynamic. So I am using destroyTooltipOnHide and similar methods. But It seems that even after using destroyTooltipOnHide doesn't remove the entire content. Because rc-trigger is creating containers on every item and they are not destroyed at all. So it's leaving a lot of these
<div style="position: absolute; top: 0px; left: 0px; width: 100%;"><div></div></div>
even after destroyPopupOnHide. There should be a way to pass either the container manually or it should destroy these containers as well.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.