From 402491743ba9df2e2d6a9285bd1777f0686c975c Mon Sep 17 00:00:00 2001
From: Tanel Vari <tavari@microsoft.com>
Date: Fri, 17 Jan 2020 14:59:04 -0800
Subject: [PATCH 1/2] Testing popup

---
 packages/react/src/components/Popup/Popup.tsx | 44 ++++++++++++++-----
 .../react/src/themes/teams/animations/fade.ts | 12 +++++
 2 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/packages/react/src/components/Popup/Popup.tsx b/packages/react/src/components/Popup/Popup.tsx
index 7245a05c52..f3ca86f5b5 100644
--- a/packages/react/src/components/Popup/Popup.tsx
+++ b/packages/react/src/components/Popup/Popup.tsx
@@ -37,6 +37,7 @@ import { createShorthandFactory, ShorthandFactory } from '../../utils/factories'
 import createReferenceFromContextClick from './createReferenceFromContextClick'
 import isRightClick from '../../utils/isRightClick'
 import PortalInner from '../Portal/PortalInner'
+import Animation from '../Animation/Animation'
 
 export type PopupEvents = 'click' | 'hover' | 'focus' | 'context'
 export type RestrictedClickEvents = 'click' | 'focus'
@@ -176,7 +177,7 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
   static defaultProps: PopupProps = {
     accessibility: popupBehavior,
     align: 'start',
-    position: 'above',
+    position: 'below',
     on: 'click',
     mouseLeaveDelay: 500,
     tabbableTrigger: true,
@@ -224,11 +225,13 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
 
     if (process.env.NODE_ENV !== 'production') {
       if (inline && trapFocus) {
+        // eslint-disable-next-line no-console
         console.warn(
           'Using "trapFocus" in inline popup leads to broken behavior for screen reader users.',
         )
       }
       if (!inline && autoFocus) {
+        // eslint-disable-next-line no-console
         console.warn(
           'Beware, "autoFocus" prop will just grab focus at the moment of mount and will not trap it. As user is able to TAB out from popup, better use "inline" prop to keep correct tab order.',
         )
@@ -250,7 +253,7 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
   }: RenderResultConfig<PopupProps>): React.ReactNode {
     const { inline, mountNode } = this.props
     const { open } = this.state
-    const popupContent = open && this.renderPopupContent(classes.popup, rtl, accessibility)
+    const popupContent = open && this.renderPopupContent(classes.popup, rtl, accessibility, open)
 
     return (
       <>
@@ -468,6 +471,7 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
     popupPositionClasses: string,
     rtl: boolean,
     accessibility: ReactAccessibilityBehavior,
+    open: boolean,
   ): JSX.Element {
     const { align, position, offset, target, unstable_pinned } = this.props
 
@@ -482,7 +486,13 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
         targetRef={
           this.rightClickReferenceObject || (target ? toRefObject(target) : this.triggerRef)
         }
-        children={this.renderPopperChildren.bind(this, popupPositionClasses, rtl, accessibility)}
+        children={this.renderPopperChildren.bind(
+          this,
+          popupPositionClasses,
+          rtl,
+          accessibility,
+          open,
+        )}
       />
     )
   }
@@ -491,6 +501,7 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
     popupPositionClasses: string,
     rtl: boolean,
     accessibility: ReactAccessibilityBehavior,
+    open: boolean,
     { placement, scheduleUpdate }: PopperChildrenProps,
   ) => {
     const {
@@ -523,18 +534,29 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
     })
 
     return (
+      // name={open ? 'spinner' : 'fadeExitSlow'}
+      // unmountOnExit
+      // mountOnEnter
+      // name={'spinner'}
       <Unstable_NestingAuto>
         {(getRefs, nestingRef) => (
           <>
-            <Ref
-              innerRef={domElement => {
-                this.popupDomElement = domElement
-                handleRef(contentRef, domElement)
-                nestingRef.current = domElement
-              }}
+            <Animation
+              name={open ? 'fadeEnterSlow' : 'spinner'}
+              visible={open}
+              timeout={5000}
+              mountOnEnter
             >
-              {popupContent}
-            </Ref>
+              <Ref
+                innerRef={domElement => {
+                  this.popupDomElement = domElement
+                  handleRef(contentRef, domElement)
+                  nestingRef.current = domElement
+                }}
+              >
+                {popupContent}
+              </Ref>
+            </Animation>
 
             <EventListener
               listener={this.handleDocumentClick(getRefs)}
diff --git a/packages/react/src/themes/teams/animations/fade.ts b/packages/react/src/themes/teams/animations/fade.ts
index 67dd9b5d13..df1dd3c6b4 100755
--- a/packages/react/src/themes/teams/animations/fade.ts
+++ b/packages/react/src/themes/teams/animations/fade.ts
@@ -1,6 +1,18 @@
 import { easeEasy } from './timingFunctions'
 
 const fadeInOutAnimations = {
+  spinner: {
+    keyframe: {
+      from: {
+        transform: 'rotate(0deg)',
+      },
+      to: {
+        transform: 'rotate(360deg)',
+      },
+    },
+    duration: '2s',
+    iterationCount: '1',
+  },
   // Basic Fade In Animation -- Fast
   fadeEnterFast: {
     keyframe: {

From d7b21b785525c4d9dd09879100bf693b865c08e3 Mon Sep 17 00:00:00 2001
From: Marija Najdova <mnajdova@gmail.com>
Date: Mon, 20 Jan 2020 14:55:33 +0100
Subject: [PATCH 2/2] -changed Animation component to accept children as fn
 -fixed Popup component

---
 .../src/components/Animation/Animation.tsx    | 22 +++++---
 packages/react/src/components/Popup/Popup.tsx | 56 ++++++++++++-------
 2 files changed, 50 insertions(+), 28 deletions(-)

diff --git a/packages/react/src/components/Animation/Animation.tsx b/packages/react/src/components/Animation/Animation.tsx
index 0ab236522b..fd6cf2020b 100644
--- a/packages/react/src/components/Animation/Animation.tsx
+++ b/packages/react/src/components/Animation/Animation.tsx
@@ -8,17 +8,18 @@ import {
   childrenExist,
   StyledComponentProps,
   commonPropTypes,
-  ChildrenComponentProps,
   ShorthandFactory,
 } from '../../utils'
 import { WithAsProp, withSafeTypeForAs } from '../../types'
 
-export interface AnimationProps
-  extends StyledComponentProps,
-    ChildrenComponentProps<React.ReactChild> {
+export type AnimationChildrenProp = (props: { classes: Record<string, string> }) => React.ReactNode
+
+export interface AnimationProps extends StyledComponentProps {
   /** Additional CSS class name(s) to apply.  */
   className?: string
 
+  children: AnimationChildrenProp | React.ReactChild
+
   /** The name for the animation that should be applied, defined in the theme. */
   name?: string
 
@@ -168,9 +169,13 @@ class Animation extends UIComponent<WithAsProp<AnimationProps>, any> {
       onExiting,
     } = this.props
 
-    const child =
-      childrenExist(children) && (React.Children.only(children) as React.ReactElement<any>)
+    // const child =
+    //   childrenExist(children) && (React.Children.only(children) as React.ReactElement<any>)
 
+    const child =
+      typeof children === 'function'
+        ? (children as AnimationChildrenProp)({ classes })
+        : childrenExist(children) && (React.Children.only(children) as React.ReactElement<any>)
     return (
       <Transition
         in={visible}
@@ -185,7 +190,10 @@ class Animation extends UIComponent<WithAsProp<AnimationProps>, any> {
         onExiting={onExiting}
         onExited={onExited}
         {...unhandledProps}
-        className={cx(classes.root, child.props.className)}
+        className={cx(
+          classes.root,
+          typeof child === 'object' && (child as any).props && (child as any).props.className,
+        )}
       >
         {child}
       </Transition>
diff --git a/packages/react/src/components/Popup/Popup.tsx b/packages/react/src/components/Popup/Popup.tsx
index f3ca86f5b5..b1872b11d6 100644
--- a/packages/react/src/components/Popup/Popup.tsx
+++ b/packages/react/src/components/Popup/Popup.tsx
@@ -8,6 +8,7 @@ import * as React from 'react'
 import * as PropTypes from 'prop-types'
 import * as keyboardKey from 'keyboard-key'
 import * as _ from 'lodash'
+import cx from 'classnames'
 
 import {
   applyAccessibilityKeyHandlers,
@@ -177,7 +178,7 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
   static defaultProps: PopupProps = {
     accessibility: popupBehavior,
     align: 'start',
-    position: 'below',
+    position: 'above',
     on: 'click',
     mouseLeaveDelay: 500,
     tabbableTrigger: true,
@@ -253,13 +254,31 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
   }: RenderResultConfig<PopupProps>): React.ReactNode {
     const { inline, mountNode } = this.props
     const { open } = this.state
-    const popupContent = open && this.renderPopupContent(classes.popup, rtl, accessibility, open)
 
     return (
       <>
         {this.renderTrigger(accessibility)}
-        {open &&
-          (inline ? popupContent : <PortalInner mountNode={mountNode}>{popupContent}</PortalInner>)}
+        <Animation
+          name={open ? 'fadeEnterSlow' : 'fadeExitSlow'}
+          visible={open}
+          timeout={500}
+          mountOnEnter
+          unmountOnExit
+        >
+          {({ classes: animationClasses }) => {
+            return inline ? (
+              this.renderPopupContent(cx(classes.popup, animationClasses.root), rtl, accessibility)
+            ) : (
+              <PortalInner mountNode={mountNode}>
+                {this.renderPopupContent(
+                  cx(classes.popup, animationClasses.root),
+                  rtl,
+                  accessibility,
+                )}
+              </PortalInner>
+            )
+          }}
+        </Animation>
       </>
     )
   }
@@ -471,7 +490,6 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
     popupPositionClasses: string,
     rtl: boolean,
     accessibility: ReactAccessibilityBehavior,
-    open: boolean,
   ): JSX.Element {
     const { align, position, offset, target, unstable_pinned } = this.props
 
@@ -522,7 +540,10 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
         ...(rtl && { dir: 'rtl' }),
         ...accessibility.attributes.popup,
         ...accessibility.keyHandlers.popup,
-        className: popupPositionClasses,
+        className: cx(
+          popupPositionClasses,
+          typeof content === 'object' && (content as any).className,
+        ),
         ...this.getContentProps(),
         placement,
         pointing,
@@ -541,22 +562,15 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
       <Unstable_NestingAuto>
         {(getRefs, nestingRef) => (
           <>
-            <Animation
-              name={open ? 'fadeEnterSlow' : 'spinner'}
-              visible={open}
-              timeout={5000}
-              mountOnEnter
+            <Ref
+              innerRef={domElement => {
+                this.popupDomElement = domElement
+                handleRef(contentRef, domElement)
+                nestingRef.current = domElement
+              }}
             >
-              <Ref
-                innerRef={domElement => {
-                  this.popupDomElement = domElement
-                  handleRef(contentRef, domElement)
-                  nestingRef.current = domElement
-                }}
-              >
-                {popupContent}
-              </Ref>
-            </Animation>
+              {popupContent}
+            </Ref>
 
             <EventListener
               listener={this.handleDocumentClick(getRefs)}