UNPKG

@uppy/informer

Version:

A notification and error pop-up bar for Uppy.

262 lines (259 loc) 8.59 kB
// INFO: not typing copy pasted libarary code // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-nocheck /* eslint-disable */ /** * @source https://github.com/developit/preact-transition-group */ import { Component, cloneElement, h, toChildArray } from 'preact'; function assign(obj, props) { return Object.assign(obj, props); } function getKey(vnode, fallback) { var _vnode$key; return (_vnode$key = vnode == null ? void 0 : vnode.key) != null ? _vnode$key : fallback; } function linkRef(component, name) { const cache = component._ptgLinkedRefs || (component._ptgLinkedRefs = {}); return cache[name] || (cache[name] = c => { component.refs[name] = c; }); } function getChildMapping(children) { const out = {}; for (let i = 0; i < children.length; i++) { if (children[i] != null) { const key = getKey(children[i], i.toString(36)); out[key] = children[i]; } } return out; } function mergeChildMappings(prev, next) { prev = prev || {}; next = next || {}; const getValueForKey = key => next.hasOwnProperty(key) ? next[key] : prev[key]; // For each key of `next`, the list of keys to insert before that key in // the combined list const nextKeysPending = {}; let pendingKeys = []; for (const prevKey in prev) { if (next.hasOwnProperty(prevKey)) { if (pendingKeys.length) { nextKeysPending[prevKey] = pendingKeys; pendingKeys = []; } } else { pendingKeys.push(prevKey); } } const childMapping = {}; for (const nextKey in next) { if (nextKeysPending.hasOwnProperty(nextKey)) { for (let i = 0; i < nextKeysPending[nextKey].length; i++) { const pendingNextKey = nextKeysPending[nextKey][i]; childMapping[nextKeysPending[nextKey][i]] = getValueForKey(pendingNextKey); } } childMapping[nextKey] = getValueForKey(nextKey); } // Finally, add the keys which didn't appear before any key in `next` for (let i = 0; i < pendingKeys.length; i++) { childMapping[pendingKeys[i]] = getValueForKey(pendingKeys[i]); } return childMapping; } const identity = i => i; class TransitionGroup extends Component { constructor(props, context) { super(props, context); this.refs = {}; this.state = { children: getChildMapping(toChildArray(toChildArray(this.props.children)) || []) }; this.performAppear = this.performAppear.bind(this); this.performEnter = this.performEnter.bind(this); this.performLeave = this.performLeave.bind(this); } componentWillMount() { this.currentlyTransitioningKeys = {}; this.keysToAbortLeave = []; this.keysToEnter = []; this.keysToLeave = []; } componentDidMount() { const initialChildMapping = this.state.children; for (const key in initialChildMapping) { if (initialChildMapping[key]) { // this.performAppear(getKey(initialChildMapping[key], key)); this.performAppear(key); } } } componentWillReceiveProps(nextProps) { const nextChildMapping = getChildMapping(toChildArray(nextProps.children) || []); const prevChildMapping = this.state.children; this.setState(prevState => ({ children: mergeChildMappings(prevState.children, nextChildMapping) })); let key; for (key in nextChildMapping) { if (nextChildMapping.hasOwnProperty(key)) { const hasPrev = prevChildMapping && prevChildMapping.hasOwnProperty(key); // We should re-enter the component and abort its leave function if (nextChildMapping[key] && hasPrev && this.currentlyTransitioningKeys[key]) { this.keysToEnter.push(key); this.keysToAbortLeave.push(key); } else if (nextChildMapping[key] && !hasPrev && !this.currentlyTransitioningKeys[key]) { this.keysToEnter.push(key); } } } for (key in prevChildMapping) { if (prevChildMapping.hasOwnProperty(key)) { const hasNext = nextChildMapping && nextChildMapping.hasOwnProperty(key); if (prevChildMapping[key] && !hasNext && !this.currentlyTransitioningKeys[key]) { this.keysToLeave.push(key); } } } } componentDidUpdate() { const { keysToEnter } = this; this.keysToEnter = []; keysToEnter.forEach(this.performEnter); const { keysToLeave } = this; this.keysToLeave = []; keysToLeave.forEach(this.performLeave); } _finishAbort(key) { const idx = this.keysToAbortLeave.indexOf(key); if (idx !== -1) { this.keysToAbortLeave.splice(idx, 1); } } performAppear(key) { this.currentlyTransitioningKeys[key] = true; const component = this.refs[key]; if (component != null && component.componentWillAppear) { component.componentWillAppear(this._handleDoneAppearing.bind(this, key)); } else { this._handleDoneAppearing(key); } } _handleDoneAppearing(key) { const component = this.refs[key]; if (component != null && component.componentDidAppear) { component.componentDidAppear(); } delete this.currentlyTransitioningKeys[key]; this._finishAbort(key); const currentChildMapping = getChildMapping(toChildArray(this.props.children) || []); if (!currentChildMapping || !currentChildMapping.hasOwnProperty(key)) { // This was removed before it had fully appeared. Remove it. this.performLeave(key); } } performEnter(key) { this.currentlyTransitioningKeys[key] = true; const component = this.refs[key]; if (component != null && component.componentWillEnter) { component.componentWillEnter(this._handleDoneEntering.bind(this, key)); } else { this._handleDoneEntering(key); } } _handleDoneEntering(key) { const component = this.refs[key]; if (component != null && component.componentDidEnter) { component.componentDidEnter(); } delete this.currentlyTransitioningKeys[key]; this._finishAbort(key); const currentChildMapping = getChildMapping(toChildArray(this.props.children) || []); if (!currentChildMapping || !currentChildMapping.hasOwnProperty(key)) { // This was removed before it had fully entered. Remove it. this.performLeave(key); } } performLeave(key) { // If we should immediately abort this leave function, // don't run the leave transition at all. const idx = this.keysToAbortLeave.indexOf(key); if (idx !== -1) { return; } this.currentlyTransitioningKeys[key] = true; const component = this.refs[key]; if (component != null && component.componentWillLeave) { component.componentWillLeave(this._handleDoneLeaving.bind(this, key)); } else { // Note that this is somewhat dangerous b/c it calls setState() // again, effectively mutating the component before all the work // is done. this._handleDoneLeaving(key); } } _handleDoneLeaving(key) { // If we should immediately abort the leave, // then skip this altogether const idx = this.keysToAbortLeave.indexOf(key); if (idx !== -1) { return; } const component = this.refs[key]; if (component != null && component.componentDidLeave) { component.componentDidLeave(); } delete this.currentlyTransitioningKeys[key]; const currentChildMapping = getChildMapping(toChildArray(this.props.children) || []); if (currentChildMapping && currentChildMapping.hasOwnProperty(key)) { // This entered again before it fully left. Add it again. this.performEnter(key); } else { const children = assign({}, this.state.children); delete children[key]; this.setState({ children }); } } render(_ref, _ref2) { let { childFactory, transitionLeave, transitionName, transitionAppear, transitionEnter, transitionLeaveTimeout, transitionEnterTimeout, transitionAppearTimeout, component, ...props } = _ref; let { children } = _ref2; // TODO: we could get rid of the need for the wrapper node // by cloning a single child const childrenToRender = Object.entries(children).map(_ref3 => { let [key, child] = _ref3; if (!child) return undefined; const ref = linkRef(this, key); return cloneElement(childFactory(child), { ref, key }); }).filter(Boolean); return h(component, props, childrenToRender); } } TransitionGroup.defaultProps = { component: 'span', childFactory: identity }; export default TransitionGroup;