From 431268ca09d7d181fbea8d583e39dbe7d6999f3a Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Mon, 10 Dec 2018 13:17:22 +0200
Subject: [PATCH 01/62] crude implementation

---
 ...opdownExampleSingleSelection.shorthand.tsx | 50 +++++++++++++++++++
 .../components/Dropdown/Types/index.tsx       |  5 ++
 src/components/Dropdown/Dropdown.tsx          | 48 ++++++++++++++----
 .../components/Dropdown/dropdownStyles.ts     | 16 ++++++
 4 files changed, 109 insertions(+), 10 deletions(-)
 create mode 100644 docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx

diff --git a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
new file mode 100644
index 0000000000..e6968e8313
--- /dev/null
+++ b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
@@ -0,0 +1,50 @@
+import * as React from 'react'
+import { Dropdown } from '@stardust-ui/react'
+
+const inputItems = [
+  'Bruce Wayne',
+  'Natasha Romanoff',
+  'Steven Strange',
+  'Alfred Pennyworth',
+  `Scarlett O'Hara`,
+  'Imperator Furiosa',
+  'Bruce Banner',
+  'Peter Parker',
+  'Selina Kyle',
+]
+
+class DropdownExample extends React.Component {
+  render() {
+    return (
+      <Dropdown
+        getA11yStatusMessage={getA11yStatusMessage}
+        noResultsMessage="We couldn't find any matches."
+        placeholder="Start typing a name"
+        items={inputItems}
+      />
+    )
+  }
+}
+
+const getA11yStatusMessage = ({
+  isOpen,
+  itemToString,
+  previousResultCount,
+  resultCount,
+  selectedItem,
+}) => {
+  if (!isOpen) {
+    return selectedItem ? itemToString(selectedItem) : ''
+  }
+  if (!resultCount) {
+    return 'No results are available.'
+  }
+  if (resultCount !== previousResultCount) {
+    return `${resultCount} result${
+      resultCount === 1 ? ' is' : 's are'
+    } available, use up and down arrow keys to navigate. Press Enter key to select.`
+  }
+  return ''
+}
+
+export default DropdownExample
diff --git a/docs/src/examples/components/Dropdown/Types/index.tsx b/docs/src/examples/components/Dropdown/Types/index.tsx
index 6a93a98f50..dc2a7499ef 100644
--- a/docs/src/examples/components/Dropdown/Types/index.tsx
+++ b/docs/src/examples/components/Dropdown/Types/index.tsx
@@ -4,6 +4,11 @@ import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'
 
 const Types = () => (
   <ExampleSection title="Types">
+    <ComponentExample
+      title="Single Selection"
+      description="A dropdown with single selection."
+      examplePath="components/Dropdown/Types/DropdownExampleSingleSelection.shorthand"
+    />
     <ComponentExample
       title="Multiple Search"
       description="A dropdown with multiple selection and search."
diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index bb7aded10a..e302fb9a49 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -30,6 +30,7 @@ import DropdownItem, { DropdownItemProps } from './DropdownItem'
 import DropdownLabel, { DropdownLabelProps } from './DropdownLabel'
 import DropdownSearchInput from './DropdownSearchInput'
 import { DropdownSearchInputProps } from 'semantic-ui-react'
+import Button from '../Button/Button'
 
 // TODO: To be replaced when Downshift will add highlightedItem in their interface.
 export interface A11yStatusMessageOptions<Item> extends DownshiftA11yStatusMessageOptions<Item> {
@@ -210,11 +211,11 @@ export default class Dropdown extends AutoControlledComponent<
       <ElementType className={classes.root} {...rest}>
         <Downshift
           onChange={this.handleSelectedChange}
-          inputValue={searchQuery}
+          inputValue={search ? searchQuery : undefined}
           stateReducer={this.handleDownshiftStateChanges}
           itemToString={itemToString}
           // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
-          selectedItem={multiple ? null : undefined}
+          selectedItem={search && !multiple ? undefined : null}
           getA11yStatusMessage={getA11yStatusMessage}
         >
           {({
@@ -233,13 +234,14 @@ export default class Dropdown extends AutoControlledComponent<
                 onClick={this.handleContainerClick.bind(this, isOpen)}
               >
                 {multiple && this.renderSelectedItems(styles)}
-                {search &&
-                  this.renderSearchInput(
-                    getRootProps,
-                    getInputProps,
-                    highlightedIndex,
-                    selectItemAtIndex,
-                  )}
+                {search
+                  ? this.renderSearchInput(
+                      getRootProps,
+                      getInputProps,
+                      highlightedIndex,
+                      selectItemAtIndex,
+                    )
+                  : this.renderTriggerButton(getToggleButtonProps, styles)}
                 {toggleButton && this.renderToggleButton(getToggleButtonProps, styles, isOpen)}
                 {this.renderItemsList(
                   styles,
@@ -257,6 +259,32 @@ export default class Dropdown extends AutoControlledComponent<
     )
   }
 
+  private renderTriggerButton(
+    getToggleButtonProps: (options?: GetToggleButtonPropsOptions) => any,
+    styles: ComponentSlotStylesInput,
+  ): JSX.Element {
+    const { placeholder, itemToString } = this.props
+    const { value } = this.state
+    return (
+      <Button
+        content={value ? itemToString(value) : placeholder}
+        fluid
+        styles={styles.button}
+        {...getToggleButtonProps({
+          onFocus: () => {
+            this.setState({ focused: true })
+          },
+          onBlur: () => {
+            this.setState({ focused: false })
+          },
+          onClick: e => {
+            e.stopPropagation()
+          },
+        })}
+      />
+    )
+  }
+
   private renderSearchInput(
     getRootProps: (options?: GetMenuPropsOptions, otherOptions?: GetPropsCommonOptions) => any,
     getInputProps: (options?: GetInputPropsOptions) => any,
@@ -611,7 +639,7 @@ export default class Dropdown extends AutoControlledComponent<
       value,
     })
     if (getA11ySelectionMessage && getA11ySelectionMessage.onRemove) {
-      this.setA11yStatus(getA11ySelectionMessage.onRemove(item))
+      this.setA11yStatus(getA11ySelectionMessage.onRemove(poppedItem))
     }
 
     // we don't have event for it, but want to keep the event handling interface, event is empty.
diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index 62436c7499..5a2120e940 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -37,6 +37,22 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
     }),
   }),
 
+  button: (): ICSSInJSStyle => {
+    const transparentColorStyle = {
+      backgroundColor: 'transparent',
+      borderColor: 'transparent',
+    }
+    return {
+      boxShadow: '0 0 0 0',
+      margin: '0',
+      justifyContent: 'left',
+      ...transparentColorStyle,
+      ':hover': transparentColorStyle,
+      ':focus': transparentColorStyle,
+      ':active': transparentColorStyle,
+    }
+  },
+
   label: (): ICSSInJSStyle => ({
     margin: '.4rem 0 0 .4rem',
   }),

From 2ee1b5e3ec9431f0437ba9736f969c59b56853ff Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Tue, 11 Dec 2018 12:14:28 +0200
Subject: [PATCH 02/62] fixed the toggle and added/refactored styles

---
 ...opdownExampleSingleSelection.shorthand.tsx |  3 +-
 src/components/Dropdown/Dropdown.tsx          | 80 ++++++++++---------
 .../Dropdown/DropdownSearchInput.tsx          | 44 +++++-----
 .../components/Dropdown/dropdownItemStyles.ts |  4 +-
 .../Dropdown/dropdownSearchInputStyles.ts     |  7 +-
 .../components/Dropdown/dropdownStyles.ts     | 38 +++++----
 .../components/Dropdown/dropdownVariables.ts  | 45 ++++++-----
 7 files changed, 116 insertions(+), 105 deletions(-)

diff --git a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
index e6968e8313..1094c540a4 100644
--- a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
@@ -18,8 +18,7 @@ class DropdownExample extends React.Component {
     return (
       <Dropdown
         getA11yStatusMessage={getA11yStatusMessage}
-        noResultsMessage="We couldn't find any matches."
-        placeholder="Start typing a name"
+        placeholder="Select your hero"
         items={inputItems}
       />
     )
diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index e302fb9a49..ef90f67ca4 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -208,38 +208,46 @@ export default class Dropdown extends AutoControlledComponent<
     const { searchQuery } = this.state
 
     return (
-      <ElementType className={classes.root} {...rest}>
-        <Downshift
-          onChange={this.handleSelectedChange}
-          inputValue={search ? searchQuery : undefined}
-          stateReducer={this.handleDownshiftStateChanges}
-          itemToString={itemToString}
-          // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
-          selectedItem={search && !multiple ? undefined : null}
-          getA11yStatusMessage={getA11yStatusMessage}
-        >
-          {({
-            getInputProps,
-            getItemProps,
-            getMenuProps,
-            getRootProps,
-            getToggleButtonProps,
-            isOpen,
-            highlightedIndex,
-            selectItemAtIndex,
-          }) => {
-            return (
-              <div
-                className={classes.containerDiv}
-                onClick={this.handleContainerClick.bind(this, isOpen)}
+      <Downshift
+        onChange={this.handleSelectedChange}
+        inputValue={search ? searchQuery : undefined}
+        stateReducer={this.handleDownshiftStateChanges}
+        itemToString={itemToString}
+        // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
+        selectedItem={search && !multiple ? undefined : null}
+        getA11yStatusMessage={getA11yStatusMessage}
+      >
+        {({
+          getInputProps,
+          getItemProps,
+          getMenuProps,
+          getRootProps,
+          getToggleButtonProps,
+          isOpen,
+          highlightedIndex,
+          selectItemAtIndex,
+        }) => {
+          const accessibilityRootProps = getRootProps(
+            { refKey: 'innerRef' },
+            { suppressRefError: true },
+          )
+          // const getExpandedRootProps = () => rootAccessibilityProps
+          const { innerRef, ...accessibilityRootPropsRest } = accessibilityRootProps
+          return (
+            <Ref innerRef={innerRef}>
+              <ElementType
+                className={classes.root}
+                onClick={multiple ? this.handleContainerClick.bind(this, isOpen) : undefined}
+                {...rest}
               >
                 {multiple && this.renderSelectedItems(styles)}
                 {search
                   ? this.renderSearchInput(
-                      getRootProps,
+                      accessibilityRootPropsRest,
                       getInputProps,
                       highlightedIndex,
                       selectItemAtIndex,
+                      variables,
                     )
                   : this.renderTriggerButton(getToggleButtonProps, styles)}
                 {toggleButton && this.renderToggleButton(getToggleButtonProps, styles, isOpen)}
@@ -251,11 +259,11 @@ export default class Dropdown extends AutoControlledComponent<
                   isOpen,
                   highlightedIndex,
                 )}
-              </div>
-            )
-          }}
-        </Downshift>
-      </ElementType>
+              </ElementType>
+            </Ref>
+          )
+        }}
+      </Downshift>
     )
   }
 
@@ -286,7 +294,7 @@ export default class Dropdown extends AutoControlledComponent<
   }
 
   private renderSearchInput(
-    getRootProps: (options?: GetMenuPropsOptions, otherOptions?: GetPropsCommonOptions) => any,
+    accessibilityComboboxProps: Object,
     getInputProps: (options?: GetInputPropsOptions) => any,
     highlightedIndex: number,
     selectItemAtIndex: (
@@ -294,6 +302,7 @@ export default class Dropdown extends AutoControlledComponent<
       otherStateToSet?: Partial<StateChangeOptions<any>>,
       cb?: () => void,
     ) => void,
+    variables,
   ): JSX.Element {
     const { searchInput, multiple, placeholder } = this.props
     const { searchQuery, value } = this.state
@@ -304,6 +313,7 @@ export default class Dropdown extends AutoControlledComponent<
     return DropdownSearchInput.create(searchInput || {}, {
       defaultProps: {
         placeholder: noPlaceholder ? '' : placeholder,
+        variables,
         inputRef: (inputNode: HTMLElement) => {
           this.inputNode = inputNode
         },
@@ -313,7 +323,7 @@ export default class Dropdown extends AutoControlledComponent<
           predefinedProps,
           highlightedIndex,
           selectItemAtIndex,
-          getRootProps,
+          accessibilityComboboxProps,
           getInputProps,
         ),
     })
@@ -524,7 +534,7 @@ export default class Dropdown extends AutoControlledComponent<
       otherStateToSet?: Partial<StateChangeOptions<any>>,
       cb?: () => void,
     ) => void,
-    getRootProps: (options?: GetMenuPropsOptions, otherOptions?: GetPropsCommonOptions) => any,
+    accessibilityComboboxProps: Object,
     getInputProps: (options?: GetInputPropsOptions) => any,
   ) => {
     const handleInputBlur = (
@@ -564,9 +574,7 @@ export default class Dropdown extends AutoControlledComponent<
         }),
       },
       // same story as above for getRootProps.
-      accessibilityWrapperProps: {
-        ...getRootProps({ refKey: 'innerRef' }, { suppressRefError: true }),
-      },
+      accessibilityComboboxProps,
       onFocus: (e: React.SyntheticEvent, searchInputProps: DropdownSearchInputProps) => {
         this.setState({ focused: true })
 
diff --git a/src/components/Dropdown/DropdownSearchInput.tsx b/src/components/Dropdown/DropdownSearchInput.tsx
index 63cec50f1d..6a4a4db94c 100644
--- a/src/components/Dropdown/DropdownSearchInput.tsx
+++ b/src/components/Dropdown/DropdownSearchInput.tsx
@@ -6,7 +6,6 @@ import { UIComponent, RenderResultConfig, createShorthandFactory, commonPropType
 import { ComponentEventHandler, ReactProps } from '../../../types/utils'
 import { UIComponentProps } from '../../lib/commonPropInterfaces'
 import Input from '../Input/Input'
-import Ref from '../Ref/Ref'
 
 export interface DropdownSearchInputProps extends UIComponentProps<DropdownSearchInputProps> {
   /**
@@ -68,7 +67,7 @@ class DropdownSearchInput extends UIComponent<ReactProps<DropdownSearchInputProp
       content: false,
     }),
     accessibilityInputProps: PropTypes.object,
-    accessibilityWrapperProps: PropTypes.object,
+    accessibilityComboboxProps: PropTypes.object,
     inputRef: PropTypes.func,
     onFocus: PropTypes.func,
     onInputBlur: PropTypes.func,
@@ -98,29 +97,26 @@ class DropdownSearchInput extends UIComponent<ReactProps<DropdownSearchInputProp
   }
 
   public renderComponent({ rest, styles }: RenderResultConfig<DropdownSearchInputProps>) {
-    const { accessibilityWrapperProps, accessibilityInputProps, placeholder } = this.props
-    const { innerRef, ...accessibilityWrapperPropsRest } = accessibilityWrapperProps
+    const { accessibilityComboboxProps, accessibilityInputProps, placeholder } = this.props
     return (
-      <Ref innerRef={innerRef}>
-        <Input
-          inputRef={this.handleInputRef}
-          onFocus={this.handleFocus}
-          onKeyUp={this.handleKeyUp}
-          wrapper={{
-            styles: styles.wrapper,
-            ...accessibilityWrapperPropsRest,
-          }}
-          input={{
-            type: 'text',
-            styles: styles.input,
-            placeholder,
-            onBlur: this.handleInputBlur,
-            onKeyDown: this.handleInputKeyDown,
-            ...accessibilityInputProps,
-          }}
-          {...rest}
-        />
-      </Ref>
+      <Input
+        inputRef={this.handleInputRef}
+        onFocus={this.handleFocus}
+        onKeyUp={this.handleKeyUp}
+        wrapper={{
+          styles: styles.combobox,
+          ...accessibilityComboboxProps,
+        }}
+        input={{
+          type: 'text',
+          styles: styles.input,
+          placeholder,
+          onBlur: this.handleInputBlur,
+          onKeyDown: this.handleInputKeyDown,
+          ...accessibilityInputProps,
+        }}
+        {...rest}
+      />
     )
   }
 }
diff --git a/src/themes/teams/components/Dropdown/dropdownItemStyles.ts b/src/themes/teams/components/Dropdown/dropdownItemStyles.ts
index bf5347c4cd..4e28dbe216 100644
--- a/src/themes/teams/components/Dropdown/dropdownItemStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownItemStyles.ts
@@ -9,8 +9,8 @@ const dropdownItemStyles: ComponentSlotStylesInput<DropdownItemProps, DropdownVa
 
     ...(active && {
       [`&.${ListItem.className}`]: {
-        backgroundColor: v.listItemHighlightedBackgroundColor,
-        color: v.listItemHighlightedTextColor,
+        backgroundColor: v.listItemBackgroundColorActive,
+        color: v.listItemColorActive,
       },
     }),
   }),
diff --git a/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts b/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
index 193a05a58c..e8a04e5c22 100644
--- a/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
@@ -6,17 +6,18 @@ const dropdownSearchInputStyles: ComponentSlotStylesInput<
   DropdownSearchInputProps,
   DropdownVariables
 > = {
-  input: ({ variables: { backgroundColor } }): ICSSInJSStyle => ({
+  input: ({ variables: { backgroundColor, comboboxPaddingInput } }): ICSSInJSStyle => ({
     width: '100%',
     backgroundColor,
+    padding: comboboxPaddingInput,
 
     ':focus': {
       borderBottomColor: 'transparent',
     },
   }),
 
-  wrapper: ({ variables: { editTextFlexBasis } }): ICSSInJSStyle => ({
-    flexBasis: editTextFlexBasis,
+  combobox: ({ variables: { comboboxFlexBasis } }): ICSSInJSStyle => ({
+    flexBasis: comboboxFlexBasis,
     flexGrow: 1,
   }),
 }
diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index 5a2120e940..b16b484fe4 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -3,16 +3,16 @@ import { DropdownProps } from '../../../../components/Dropdown/Dropdown'
 import { DropdownVariables } from './dropdownVariables'
 
 const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables> = {
-  containerDiv: ({
+  root: ({
     props: { focused, toggleButton, fluid },
     variables: {
       backgroundColor,
-      containerDivBorderBottom,
-      containerDivBorderRadius,
-      containerDivBorderColor,
-      containerDivFocusBorderColor,
-      containerDivFocusBorderRadius,
-      containerDivColor,
+      borderBottom,
+      borderRadius,
+      borderColor,
+      borderColorFocus,
+      borderRadiusFocus,
+      color,
       toggleButtonSize,
       width,
     },
@@ -22,33 +22,39 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
     outline: 0,
     border: 0,
     backgroundColor,
-    borderRadius: containerDivBorderRadius,
-    borderBottom: containerDivBorderBottom,
-    borderColor: containerDivBorderColor,
-    color: containerDivColor,
+    borderBottom,
+    borderColor,
+    borderRadius,
+    color,
     width: fluid ? '100%' : width,
     position: 'relative',
     ...(toggleButton && {
       paddingRight: toggleButtonSize,
     }),
     ...(focused && {
-      borderColor: containerDivFocusBorderColor,
-      borderRadius: containerDivFocusBorderRadius,
+      borderColor: borderColorFocus,
+      borderRadius: borderRadiusFocus,
     }),
   }),
 
-  button: (): ICSSInJSStyle => {
+  button: ({ variables: { comboboxPaddingButton } }): ICSSInJSStyle => {
     const transparentColorStyle = {
       backgroundColor: 'transparent',
       borderColor: 'transparent',
     }
     return {
-      boxShadow: '0 0 0 0',
+      boxShadow: 'none',
       margin: '0',
       justifyContent: 'left',
+      padding: comboboxPaddingButton,
       ...transparentColorStyle,
       ':hover': transparentColorStyle,
-      ':focus': transparentColorStyle,
+      ':focus': {
+        ...transparentColorStyle,
+        ':after': {
+          borderColor: 'transparent',
+        },
+      },
       ':active': transparentColorStyle,
     }
   },
diff --git a/src/themes/teams/components/Dropdown/dropdownVariables.ts b/src/themes/teams/components/Dropdown/dropdownVariables.ts
index 32c59c7fd2..95319720d2 100644
--- a/src/themes/teams/components/Dropdown/dropdownVariables.ts
+++ b/src/themes/teams/components/Dropdown/dropdownVariables.ts
@@ -1,39 +1,40 @@
 import { pxToRem } from '../../utils'
 export interface DropdownVariables {
   backgroundColor: string
-  containerDivBorderRadius: string
-  containerDivBorderBottom: string
-  containerDivBorderColor: string
-  containerDivColor: string
-  containerDivFocusBorderColor: string
-  containerDivFocusBorderRadius: string
-  editTextFlexBasis: string
+  borderBottom: string
+  borderColor: string
+  borderColorFocus: string
+  borderRadius: string
+  borderRadiusFocus: string
+  color: string
+  comboboxPaddingButton: string
+  comboboxPaddingInput: string
+  comboboxFlexBasis: string
   listItemBackgroundColor: string
-  listItemHighlightedBackgroundColor: string
-  listItemHighlightedTextColor: string
+  listItemBackgroundColorActive: string
+  listItemColorActive: string
   listMaxHeight: string
   toggleButtonSize: string
   width: string
 }
 
-const [_2px_asRem, _3px_asRem] = [2, 3].map(v => pxToRem(v))
+const [_2px_asRem, _3px_asRem, _6px_asRem, _12px_asRem] = [2, 3, 6, 12].map(v => pxToRem(v))
 
 export default (siteVars): DropdownVariables => ({
   backgroundColor: siteVars.gray10,
-
-  containerDivBorderRadius: _3px_asRem,
-  containerDivBorderBottom: `${_2px_asRem} solid transparent`,
-  containerDivBorderColor: 'transparent',
-  containerDivColor: siteVars.bodyColor,
-  containerDivFocusBorderColor: siteVars.brand,
-  containerDivFocusBorderRadius: `${_3px_asRem} ${_3px_asRem} ${_2px_asRem} ${_2px_asRem}`,
-  editTextFlexBasis: '100px',
-
+  borderRadius: _3px_asRem,
+  borderBottom: `${_2px_asRem} solid transparent`,
+  borderColor: 'transparent',
+  borderColorFocus: siteVars.brand,
+  borderRadiusFocus: `${_3px_asRem} ${_3px_asRem} ${_2px_asRem} ${_2px_asRem}`,
+  color: siteVars.bodyColor,
+  comboboxPaddingButton: `0 ${_12px_asRem}`,
+  comboboxPaddingInput: `${_6px_asRem} ${_12px_asRem}`,
+  comboboxFlexBasis: '50px',
   listItemBackgroundColor: siteVars.white,
-  listItemHighlightedBackgroundColor: siteVars.brand,
-  listItemHighlightedTextColor: siteVars.white,
+  listItemBackgroundColorActive: siteVars.brand,
+  listItemColorActive: siteVars.white,
   listMaxHeight: '20rem',
-
   toggleButtonSize: pxToRem(30),
   width: pxToRem(356),
 })

From b959dd990c412542c37cb8da997caa463f24569c Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Tue, 11 Dec 2018 13:17:36 +0200
Subject: [PATCH 03/62] fixed the filtering to work for all variants

---
 src/components/Dropdown/Dropdown.tsx | 42 +++++++++++++++-------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index ef90f67ca4..22acc7cef6 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -231,7 +231,6 @@ export default class Dropdown extends AutoControlledComponent<
             { refKey: 'innerRef' },
             { suppressRefError: true },
           )
-          // const getExpandedRootProps = () => rootAccessibilityProps
           const { innerRef, ...accessibilityRootPropsRest } = accessibilityRootProps
           return (
             <Ref innerRef={innerRef}>
@@ -374,8 +373,8 @@ export default class Dropdown extends AutoControlledComponent<
     getItemProps: (options: GetItemPropsOptions<ShorthandValue>) => any,
     highlightedIndex: number,
   ) {
-    const { items, noResultsMessage } = this.props
-    const filteredItems = this.getItemsFilteredBySearchQuery(items)
+    const { noResultsMessage } = this.props
+    const filteredItems = this.getFilteredItems()
 
     if (filteredItems.length > 0) {
       return filteredItems.map((item, index) => {
@@ -457,25 +456,30 @@ export default class Dropdown extends AutoControlledComponent<
     }
   }
 
-  private getItemsFilteredBySearchQuery = (items: ShorthandValue[]): ShorthandValue[] => {
-    const { itemToString, multiple, search } = this.props
+  private getFilteredItems = (): ShorthandValue[] => {
+    const { items, itemToString, multiple, search } = this.props
     const { searchQuery, value } = this.state
+    let filteredItems = items
 
-    const nonSelectedItems = items.filter(item =>
-      multiple ? (value as ShorthandValue[]).indexOf(item) === -1 : true,
-    )
-
-    const itemsMatchSearchQuery = nonSelectedItems.filter(item =>
-      search
-        ? _.isFunction(search)
-          ? search(itemsMatchSearchQuery, searchQuery)
-          : itemToString(item)
-              .toLowerCase()
-              .indexOf(searchQuery.toLowerCase()) !== -1
-        : true,
-    )
+    if (!multiple && !search) {
+      return items.filter(item => item !== (value as ShorthandValue))
+    }
+    if (multiple) {
+      filteredItems = filteredItems.filter(item => (value as ShorthandValue[]).indexOf(item) === -1)
+    }
+    if (search) {
+      if (_.isFunction(search)) {
+        return search(filteredItems, searchQuery)
+      }
+      return filteredItems.filter(
+        item =>
+          itemToString(item)
+            .toLowerCase()
+            .indexOf(searchQuery.toLowerCase()) !== -1,
+      )
+    }
 
-    return itemsMatchSearchQuery
+    return filteredItems
   }
 
   private setA11yStatus = (statusMessage: string) => {

From c0482c54c0b5286e40f2ea531b5ae02321966f31 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Tue, 11 Dec 2018 13:25:56 +0200
Subject: [PATCH 04/62] made the toggleButton tabbable by default

---
 src/components/Dropdown/Dropdown.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 22acc7cef6..7a6ffe243d 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -337,7 +337,7 @@ export default class Dropdown extends AutoControlledComponent<
       <Icon
         name={`chevron ${isOpen ? 'up' : 'down'}`}
         as="button"
-        tabIndex="-1"
+        tabIndex="0"
         styles={styles.toggleButton}
         {...getToggleButtonProps()}
       />

From 5fe6ed74504e311d17cd655f09b6b8c8367aebf4 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Tue, 11 Dec 2018 13:31:22 +0200
Subject: [PATCH 05/62] fixed style case active+focus

---
 src/themes/teams/components/Dropdown/dropdownStyles.ts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index b16b484fe4..08b91d8ebf 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -54,6 +54,7 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
         ':after': {
           borderColor: 'transparent',
         },
+        ':active': transparentColorStyle,
       },
       ':active': transparentColorStyle,
     }

From 8a8882d6748e1390a93cdec61db977f3216e4b29 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Tue, 11 Dec 2018 15:46:49 +0200
Subject: [PATCH 06/62] fixed wrong import

---
 src/components/Dropdown/Dropdown.tsx | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 7a6ffe243d..564c11c38b 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -28,8 +28,7 @@ import Ref from '../Ref/Ref'
 import { UIComponentProps } from '../../lib/commonPropInterfaces'
 import DropdownItem, { DropdownItemProps } from './DropdownItem'
 import DropdownLabel, { DropdownLabelProps } from './DropdownLabel'
-import DropdownSearchInput from './DropdownSearchInput'
-import { DropdownSearchInputProps } from 'semantic-ui-react'
+import DropdownSearchInput, { DropdownSearchInputProps } from './DropdownSearchInput'
 import Button from '../Button/Button'
 
 // TODO: To be replaced when Downshift will add highlightedItem in their interface.
@@ -352,7 +351,7 @@ export default class Dropdown extends AutoControlledComponent<
     isOpen: boolean,
     highlightedIndex: number,
   ) {
-    const accessibilityMenuProps = getMenuProps({ refKey: 'innerRef' })
+    const accessibilityMenuProps = getMenuProps({ refKey: 'innerRef' }, { suppressRefError: true })
     const { innerRef, ...accessibilityMenuPropsRest } = accessibilityMenuProps
 
     return (

From 92ad9c0057d0dfac185c9b921766ef163c5fb43e Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Tue, 11 Dec 2018 17:09:29 +0200
Subject: [PATCH 07/62] fixed ariaLabel for trigger button

---
 src/components/Dropdown/Dropdown.tsx | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 564c11c38b..ee465d6ba8 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -269,11 +269,12 @@ export default class Dropdown extends AutoControlledComponent<
     getToggleButtonProps: (options?: GetToggleButtonPropsOptions) => any,
     styles: ComponentSlotStylesInput,
   ): JSX.Element {
-    const { placeholder, itemToString } = this.props
+    const { placeholder, itemToString, multiple } = this.props
     const { value } = this.state
+    const content = multiple ? placeholder : value ? itemToString(value) : placeholder
     return (
       <Button
-        content={value ? itemToString(value) : placeholder}
+        content={content}
         fluid
         styles={styles.button}
         {...getToggleButtonProps({
@@ -286,6 +287,7 @@ export default class Dropdown extends AutoControlledComponent<
           onClick: e => {
             e.stopPropagation()
           },
+          'aria-label': content, // TODO: add this to behaviour
         })}
       />
     )

From 55e980740e237cc6f934adb7f2f3b9500a611912 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Wed, 12 Dec 2018 18:14:05 +0200
Subject: [PATCH 08/62] added list focus and accessibility handling for it

---
 ...opdownExampleSingleSelection.shorthand.tsx |   3 +
 src/components/Dropdown/Dropdown.tsx          | 121 ++++++++++++++----
 2 files changed, 99 insertions(+), 25 deletions(-)

diff --git a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
index 1094c540a4..1145fb1b6c 100644
--- a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
@@ -18,6 +18,9 @@ class DropdownExample extends React.Component {
     return (
       <Dropdown
         getA11yStatusMessage={getA11yStatusMessage}
+        getA11ySelectionMessage={{
+          onAdd: item => `${item} has been selected.`,
+        }}
         placeholder="Select your hero"
         items={inputItems}
       />
diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index ee465d6ba8..eb21b562d4 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -131,6 +131,8 @@ export default class Dropdown extends AutoControlledComponent<
   DropdownState
 > {
   private inputNode: HTMLElement
+  private listNode: HTMLElement
+  private buttonNode: HTMLElement
 
   static displayName = 'Dropdown'
 
@@ -215,6 +217,11 @@ export default class Dropdown extends AutoControlledComponent<
         // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
         selectedItem={search && !multiple ? undefined : null}
         getA11yStatusMessage={getA11yStatusMessage}
+        onStateChange={changes => {
+          if (changes.isOpen && !search) {
+            this.listNode.focus()
+          }
+        }}
       >
         {({
           getInputProps,
@@ -223,6 +230,7 @@ export default class Dropdown extends AutoControlledComponent<
           getRootProps,
           getToggleButtonProps,
           isOpen,
+          toggleMenu,
           highlightedIndex,
           selectItemAtIndex,
         }) => {
@@ -247,15 +255,18 @@ export default class Dropdown extends AutoControlledComponent<
                       selectItemAtIndex,
                       variables,
                     )
-                  : this.renderTriggerButton(getToggleButtonProps, styles)}
+                  : this.renderTriggerButton(styles, getToggleButtonProps)}
                 {toggleButton && this.renderToggleButton(getToggleButtonProps, styles, isOpen)}
                 {this.renderItemsList(
                   styles,
                   variables,
-                  getMenuProps,
-                  getItemProps,
                   isOpen,
                   highlightedIndex,
+                  toggleMenu,
+                  selectItemAtIndex,
+                  getMenuProps,
+                  getItemProps,
+                  getInputProps,
                 )}
               </ElementType>
             </Ref>
@@ -266,30 +277,33 @@ export default class Dropdown extends AutoControlledComponent<
   }
 
   private renderTriggerButton(
-    getToggleButtonProps: (options?: GetToggleButtonPropsOptions) => any,
     styles: ComponentSlotStylesInput,
+    getToggleButtonProps: (options?: GetToggleButtonPropsOptions) => any,
   ): JSX.Element {
     const { placeholder, itemToString, multiple } = this.props
     const { value } = this.state
     const content = multiple ? placeholder : value ? itemToString(value) : placeholder
     return (
-      <Button
-        content={content}
-        fluid
-        styles={styles.button}
-        {...getToggleButtonProps({
-          onFocus: () => {
-            this.setState({ focused: true })
-          },
-          onBlur: () => {
-            this.setState({ focused: false })
-          },
-          onClick: e => {
-            e.stopPropagation()
-          },
-          'aria-label': content, // TODO: add this to behaviour
-        })}
-      />
+      <Ref
+        innerRef={buttonNode => {
+          this.buttonNode = buttonNode
+        }}
+      >
+        <Button
+          content={content}
+          fluid
+          styles={styles.button}
+          {...getToggleButtonProps({
+            onFocus: () => {
+              this.setState({ focused: true })
+            },
+            onBlur: () => {
+              this.setState({ focused: false })
+            },
+            'aria-label': content, // TODO: add this to behaviour
+          })}
+        />
+      </Ref>
     )
   }
 
@@ -348,19 +362,44 @@ export default class Dropdown extends AutoControlledComponent<
   private renderItemsList(
     styles: ComponentSlotStylesInput,
     variables: ComponentVariablesInput,
-    getMenuProps: (options?: GetMenuPropsOptions, otherOptions?: GetPropsCommonOptions) => any,
-    getItemProps: (options: GetItemPropsOptions<ShorthandValue>) => any,
     isOpen: boolean,
     highlightedIndex: number,
+    toggleMenu: () => void,
+    selectItemAtIndex: (index: number) => void,
+    getMenuProps: (options?: GetMenuPropsOptions, otherOptions?: GetPropsCommonOptions) => any,
+    getItemProps: (options: GetItemPropsOptions<ShorthandValue>) => any,
+    getInputProps: (options?: GetInputPropsOptions) => any,
   ) {
-    const accessibilityMenuProps = getMenuProps({ refKey: 'innerRef' }, { suppressRefError: true })
+    const accessibilityMenuProps = {
+      ...getMenuProps({ refKey: 'innerRef' }, { suppressRefError: true }),
+    }
+    if (!this.props.search) {
+      const accessibilityInputProps = getInputProps()
+      accessibilityMenuProps['aria-activedescendant'] =
+        accessibilityInputProps['aria-activedescendant']
+      accessibilityMenuProps['onKeyDown'] = e => {
+        this.handleListKeyDown(
+          e,
+          highlightedIndex,
+          accessibilityInputProps['onKeyDown'],
+          toggleMenu,
+          selectItemAtIndex,
+        )
+      }
+    }
     const { innerRef, ...accessibilityMenuPropsRest } = accessibilityMenuProps
 
     return (
-      <Ref innerRef={innerRef}>
+      <Ref
+        innerRef={(listNode: HTMLElement) => {
+          this.listNode = listNode
+          innerRef(listNode)
+        }}
+      >
         <List
           {...accessibilityMenuPropsRest}
           styles={styles.list}
+          tabIndex={-1}
           aria-hidden={!isOpen}
           items={isOpen ? this.renderItems(styles, variables, getItemProps, highlightedIndex) : []}
         />
@@ -452,6 +491,12 @@ export default class Dropdown extends AutoControlledComponent<
           { ...this.props, searchQuery: changes.inputValue },
         )
         return changes
+      case Downshift.stateChangeTypes.blurButton:
+        // Focus the list, by button click/enter/up/down/space. Downshift, by default, closes the list
+        // on trigger blur, but in this case it's custom behaviour, where we want to keep it open.
+        if (state.isOpen) {
+          return {}
+        }
       default:
         return changes
     }
@@ -615,6 +660,32 @@ export default class Dropdown extends AutoControlledComponent<
     !isOpen && this.inputNode.focus()
   }
 
+  private handleListKeyDown = (
+    e: React.SyntheticEvent,
+    highlightedIndex: number,
+    accessibilityInputPropsKeyDown: (e) => any,
+    toggleMenu: () => void,
+    selectItemAtIndex: (index: number) => void,
+  ) => {
+    switch (keyboardKey.getCode(e)) {
+      case keyboardKey.Tab:
+        if (_.isNil(highlightedIndex)) {
+          toggleMenu()
+        } else {
+          selectItemAtIndex(highlightedIndex)
+        }
+        return
+      case keyboardKey.Enter:
+      case keyboardKey.Escape:
+        accessibilityInputPropsKeyDown(e)
+        this.buttonNode.focus()
+        return
+      default:
+        accessibilityInputPropsKeyDown(e)
+        return
+    }
+  }
+
   private handleSelectedChange = (item: ShorthandValue) => {
     const { multiple, getA11ySelectionMessage } = this.props
     const newValue = multiple ? [...(this.state.value as ShorthandValue[]), item] : item

From 0f294b2451b596d6b709065ebf50f285b140ed0c Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 13 Dec 2018 10:14:21 +0200
Subject: [PATCH 09/62] fixed toggle button bug that appeared after trigger fix

---
 src/components/Dropdown/Dropdown.tsx | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index eb21b562d4..a0e850ee64 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -492,10 +492,10 @@ export default class Dropdown extends AutoControlledComponent<
         )
         return changes
       case Downshift.stateChangeTypes.blurButton:
-        // Focus the list, by button click/enter/up/down/space. Downshift, by default, closes the list
-        // on trigger blur, but in this case it's custom behaviour, where we want to keep it open.
-        if (state.isOpen) {
-          return {}
+        // Downshift closes the list by default on trigger blur. It does not support the case when dropdown is
+        // single selection and focuses list on trigger click/up/down/space/enter. Treating that here.
+        if (state.isOpen && document.activeElement === this.listNode) {
+          return {} // won't change state in this case.
         }
       default:
         return changes
@@ -599,7 +599,7 @@ export default class Dropdown extends AutoControlledComponent<
       e: React.SyntheticEvent,
       searchInputProps: DropdownSearchInputProps,
     ) => {
-      if (keyboardKey.getCode(e) === keyboardKey.Tab && highlightedIndex !== undefined) {
+      if (keyboardKey.getCode(e) === keyboardKey.Tab && _.isNil(highlightedIndex)) {
         selectItemAtIndex(highlightedIndex)
       }
 

From 27396f122fdf19a422bc6e43f586ee130c86cd79 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 13 Dec 2018 11:23:21 +0200
Subject: [PATCH 10/62] reverted change for filteredItems

---
 src/components/Dropdown/Dropdown.tsx | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index a0e850ee64..3b014c41bf 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -414,7 +414,7 @@ export default class Dropdown extends AutoControlledComponent<
     highlightedIndex: number,
   ) {
     const { noResultsMessage } = this.props
-    const filteredItems = this.getFilteredItems()
+    const filteredItems = this.getItemsFilteredBySearchQuery()
 
     if (filteredItems.length > 0) {
       return filteredItems.map((item, index) => {
@@ -502,14 +502,11 @@ export default class Dropdown extends AutoControlledComponent<
     }
   }
 
-  private getFilteredItems = (): ShorthandValue[] => {
+  private getItemsFilteredBySearchQuery = (): ShorthandValue[] => {
     const { items, itemToString, multiple, search } = this.props
     const { searchQuery, value } = this.state
     let filteredItems = items
 
-    if (!multiple && !search) {
-      return items.filter(item => item !== (value as ShorthandValue))
-    }
     if (multiple) {
       filteredItems = filteredItems.filter(item => (value as ShorthandValue[]).indexOf(item) === -1)
     }

From 35d7e530c5a34ea22a1778d8523e0b083c0cc555 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 13 Dec 2018 11:52:53 +0200
Subject: [PATCH 11/62] refactored the renderComponent to pass conformance

---
 src/components/Dropdown/Dropdown.tsx          | 129 +++++++++---------
 .../components/Dropdown/dropdownStyles.ts     |   4 +-
 2 files changed, 68 insertions(+), 65 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 3b014c41bf..7218a198b1 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -209,70 +209,71 @@ export default class Dropdown extends AutoControlledComponent<
     const { searchQuery } = this.state
 
     return (
-      <Downshift
-        onChange={this.handleSelectedChange}
-        inputValue={search ? searchQuery : undefined}
-        stateReducer={this.handleDownshiftStateChanges}
-        itemToString={itemToString}
-        // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
-        selectedItem={search && !multiple ? undefined : null}
-        getA11yStatusMessage={getA11yStatusMessage}
-        onStateChange={changes => {
-          if (changes.isOpen && !search) {
-            this.listNode.focus()
-          }
-        }}
-      >
-        {({
-          getInputProps,
-          getItemProps,
-          getMenuProps,
-          getRootProps,
-          getToggleButtonProps,
-          isOpen,
-          toggleMenu,
-          highlightedIndex,
-          selectItemAtIndex,
-        }) => {
-          const accessibilityRootProps = getRootProps(
-            { refKey: 'innerRef' },
-            { suppressRefError: true },
-          )
-          const { innerRef, ...accessibilityRootPropsRest } = accessibilityRootProps
-          return (
-            <Ref innerRef={innerRef}>
-              <ElementType
-                className={classes.root}
-                onClick={multiple ? this.handleContainerClick.bind(this, isOpen) : undefined}
-                {...rest}
-              >
-                {multiple && this.renderSelectedItems(styles)}
-                {search
-                  ? this.renderSearchInput(
-                      accessibilityRootPropsRest,
-                      getInputProps,
-                      highlightedIndex,
-                      selectItemAtIndex,
-                      variables,
-                    )
-                  : this.renderTriggerButton(styles, getToggleButtonProps)}
-                {toggleButton && this.renderToggleButton(getToggleButtonProps, styles, isOpen)}
-                {this.renderItemsList(
-                  styles,
-                  variables,
-                  isOpen,
-                  highlightedIndex,
-                  toggleMenu,
-                  selectItemAtIndex,
-                  getMenuProps,
-                  getItemProps,
-                  getInputProps,
-                )}
-              </ElementType>
-            </Ref>
-          )
-        }}
-      </Downshift>
+      <ElementType className={classes.root} {...rest}>
+        <Downshift
+          onChange={this.handleSelectedChange}
+          inputValue={search ? searchQuery : undefined}
+          stateReducer={this.handleDownshiftStateChanges}
+          itemToString={itemToString}
+          // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
+          selectedItem={search && !multiple ? undefined : null}
+          getA11yStatusMessage={getA11yStatusMessage}
+          onStateChange={changes => {
+            if (changes.isOpen && !search) {
+              this.listNode.focus()
+            }
+          }}
+        >
+          {({
+            getInputProps,
+            getItemProps,
+            getMenuProps,
+            getRootProps,
+            getToggleButtonProps,
+            isOpen,
+            toggleMenu,
+            highlightedIndex,
+            selectItemAtIndex,
+          }) => {
+            const accessibilityRootProps = getRootProps(
+              { refKey: 'innerRef' },
+              { suppressRefError: true },
+            )
+            const { innerRef, ...accessibilityRootPropsRest } = accessibilityRootProps
+            return (
+              <Ref innerRef={innerRef}>
+                <div
+                  className={classes.container}
+                  onClick={multiple ? this.handleContainerClick.bind(this, isOpen) : undefined}
+                >
+                  {multiple && this.renderSelectedItems(styles)}
+                  {search
+                    ? this.renderSearchInput(
+                        accessibilityRootPropsRest,
+                        getInputProps,
+                        highlightedIndex,
+                        selectItemAtIndex,
+                        variables,
+                      )
+                    : this.renderTriggerButton(styles, getToggleButtonProps)}
+                  {toggleButton && this.renderToggleButton(getToggleButtonProps, styles, isOpen)}
+                  {this.renderItemsList(
+                    styles,
+                    variables,
+                    isOpen,
+                    highlightedIndex,
+                    toggleMenu,
+                    selectItemAtIndex,
+                    getMenuProps,
+                    getItemProps,
+                    getInputProps,
+                  )}
+                </div>
+              </Ref>
+            )
+          }}
+        </Downshift>
+      </ElementType>
     )
   }
 
diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index 08b91d8ebf..81639105b9 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -3,7 +3,9 @@ import { DropdownProps } from '../../../../components/Dropdown/Dropdown'
 import { DropdownVariables } from './dropdownVariables'
 
 const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables> = {
-  root: ({
+  root: (): ICSSInJSStyle => ({}),
+
+  container: ({
     props: { focused, toggleButton, fluid },
     variables: {
       backgroundColor,

From fc64c6df648d7bb974d2addd55750a602f37dfb4 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 13 Dec 2018 11:55:50 +0200
Subject: [PATCH 12/62] fixed button focus at selection

---
 src/components/Dropdown/Dropdown.tsx | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 7218a198b1..ca43a881bf 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -673,7 +673,6 @@ export default class Dropdown extends AutoControlledComponent<
           selectItemAtIndex(highlightedIndex)
         }
         return
-      case keyboardKey.Enter:
       case keyboardKey.Escape:
         accessibilityInputPropsKeyDown(e)
         this.buttonNode.focus()
@@ -685,7 +684,7 @@ export default class Dropdown extends AutoControlledComponent<
   }
 
   private handleSelectedChange = (item: ShorthandValue) => {
-    const { multiple, getA11ySelectionMessage } = this.props
+    const { multiple, getA11ySelectionMessage, search } = this.props
     const newValue = multiple ? [...(this.state.value as ShorthandValue[]), item] : item
 
     this.trySetState({
@@ -695,6 +694,9 @@ export default class Dropdown extends AutoControlledComponent<
     if (getA11ySelectionMessage && getA11ySelectionMessage.onAdd) {
       this.setA11yStatus(getA11ySelectionMessage.onAdd(item))
     }
+    if (!search) {
+      this.buttonNode.focus()
+    }
 
     // we don't have event for it, but want to keep the event handling interface, event is empty.
     _.invoke(this.props, 'onSelectedChange', {}, { ...this.props, value: newValue })

From 8b24b0cb14525439cf35423ff372e4df1862b915 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 13 Dec 2018 18:39:39 +0200
Subject: [PATCH 13/62] merged ref code review improvement

---
 src/components/Dropdown/Dropdown.tsx | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index ca43a881bf..2a01dc3538 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -132,7 +132,7 @@ export default class Dropdown extends AutoControlledComponent<
 > {
   private inputNode: HTMLElement
   private listNode: HTMLElement
-  private buttonNode: HTMLElement
+  private buttonRef = React.createRef<HTMLElement>()
 
   static displayName = 'Dropdown'
 
@@ -285,11 +285,7 @@ export default class Dropdown extends AutoControlledComponent<
     const { value } = this.state
     const content = multiple ? placeholder : value ? itemToString(value) : placeholder
     return (
-      <Ref
-        innerRef={buttonNode => {
-          this.buttonNode = buttonNode
-        }}
-      >
+      <Ref innerRef={this.buttonRef}>
         <Button
           content={content}
           fluid
@@ -675,7 +671,7 @@ export default class Dropdown extends AutoControlledComponent<
         return
       case keyboardKey.Escape:
         accessibilityInputPropsKeyDown(e)
-        this.buttonNode.focus()
+        this.buttonRef.current.focus()
         return
       default:
         accessibilityInputPropsKeyDown(e)
@@ -695,7 +691,7 @@ export default class Dropdown extends AutoControlledComponent<
       this.setA11yStatus(getA11ySelectionMessage.onAdd(item))
     }
     if (!search) {
-      this.buttonNode.focus()
+      this.buttonRef.current.focus()
     }
 
     // we don't have event for it, but want to keep the event handling interface, event is empty.

From a2b3424d236ecb3a7ed8f6e94ff26973d4fac205 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 13 Dec 2018 19:17:00 +0200
Subject: [PATCH 14/62] removed unneeded code

---
 src/components/Dropdown/Dropdown.tsx | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 2a01dc3538..bf88d1e7b5 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -415,13 +415,7 @@ export default class Dropdown extends AutoControlledComponent<
 
     if (filteredItems.length > 0) {
       return filteredItems.map((item, index) => {
-        let itemAsListItem = item
-        if (typeof item === 'object') {
-          itemAsListItem = _.pickBy(item, (value, key) =>
-            _.includes(['key', ...DropdownItem.handledProps], key),
-          )
-        }
-        return DropdownItem.create(itemAsListItem, {
+        return DropdownItem.create(item, {
           defaultProps: {
             active: highlightedIndex === index,
             variables,

From bc88b891cab9b5581db93fbc53ed7de3a6c842a3 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Fri, 14 Dec 2018 11:37:30 +0200
Subject: [PATCH 15/62] removed ternary condition

---
 src/components/Dropdown/Dropdown.tsx | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index bf88d1e7b5..0ce06179ff 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -283,7 +283,14 @@ export default class Dropdown extends AutoControlledComponent<
   ): JSX.Element {
     const { placeholder, itemToString, multiple } = this.props
     const { value } = this.state
-    const content = multiple ? placeholder : value ? itemToString(value) : placeholder
+    let content
+
+    if (multiple) {
+      content = placeholder
+    } else {
+      content = value ? itemToString(value) : placeholder
+    }
+
     return (
       <Ref innerRef={this.buttonRef}>
         <Button

From eabbbe10ece8a42c231424660908346514dacdc0 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Wed, 2 Jan 2019 17:11:49 +0200
Subject: [PATCH 16/62] replaced some heights to make toggle button appear
 centered

---
 src/themes/teams/components/Dropdown/dropdownStyles.ts    | 2 ++
 src/themes/teams/components/Dropdown/dropdownVariables.ts | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index 81639105b9..446b22fb4a 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -1,6 +1,7 @@
 import { ComponentSlotStylesInput, ICSSInJSStyle } from '../../../types'
 import { DropdownProps } from '../../../../components/Dropdown/Dropdown'
 import { DropdownVariables } from './dropdownVariables'
+import { pxToRem } from '../../utils'
 
 const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables> = {
   root: (): ICSSInJSStyle => ({}),
@@ -50,6 +51,7 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
       justifyContent: 'left',
       padding: comboboxPaddingButton,
       ...transparentColorStyle,
+      height: pxToRem(30),
       ':hover': transparentColorStyle,
       ':focus': {
         ...transparentColorStyle,
diff --git a/src/themes/teams/components/Dropdown/dropdownVariables.ts b/src/themes/teams/components/Dropdown/dropdownVariables.ts
index 95319720d2..d92e33e739 100644
--- a/src/themes/teams/components/Dropdown/dropdownVariables.ts
+++ b/src/themes/teams/components/Dropdown/dropdownVariables.ts
@@ -35,6 +35,6 @@ export default (siteVars): DropdownVariables => ({
   listItemBackgroundColorActive: siteVars.brand,
   listItemColorActive: siteVars.white,
   listMaxHeight: '20rem',
-  toggleButtonSize: pxToRem(30),
+  toggleButtonSize: pxToRem(32),
   width: pxToRem(356),
 })

From 50700a40c2770648110ba23c3ee3203cc181dec0 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Wed, 2 Jan 2019 19:05:39 +0200
Subject: [PATCH 17/62] improvements on styles from code review

---
 src/components/Dropdown/Dropdown.tsx               | 14 ++++++++------
 src/components/Dropdown/DropdownSearchInput.tsx    |  3 +++
 .../Dropdown/dropdownSearchInputStyles.ts          |  8 +++++++-
 .../teams/components/Dropdown/dropdownStyles.ts    | 11 +++++------
 4 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 0ce06179ff..f3a8f9d6bc 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -304,7 +304,6 @@ export default class Dropdown extends AutoControlledComponent<
             onBlur: () => {
               this.setState({ focused: false })
             },
-            'aria-label': content, // TODO: add this to behaviour
           })}
         />
       </Ref>
@@ -322,7 +321,7 @@ export default class Dropdown extends AutoControlledComponent<
     ) => void,
     variables,
   ): JSX.Element {
-    const { searchInput, multiple, placeholder } = this.props
+    const { searchInput, multiple, placeholder, toggleButton } = this.props
     const { searchQuery, value } = this.state
 
     const noPlaceholder =
@@ -331,6 +330,7 @@ export default class Dropdown extends AutoControlledComponent<
     return DropdownSearchInput.create(searchInput || {}, {
       defaultProps: {
         placeholder: noPlaceholder ? '' : placeholder,
+        hasToggleButton: !!toggleButton,
         variables,
         inputRef: (inputNode: HTMLElement) => {
           this.inputNode = inputNode
@@ -352,13 +352,15 @@ export default class Dropdown extends AutoControlledComponent<
     styles: ComponentSlotStylesInput,
     isOpen: boolean,
   ) {
+    const { onClick, onBlur, onKeyDown, onKeyUp } = getToggleButtonProps()
     return (
       <Icon
         name={`chevron ${isOpen ? 'up' : 'down'}`}
-        as="button"
-        tabIndex="0"
         styles={styles.toggleButton}
-        {...getToggleButtonProps()}
+        onClick={onClick}
+        onBlur={onBlur}
+        onKeyDown={onKeyDown}
+        onKeyUp={onKeyUp}
       />
     )
   }
@@ -594,7 +596,7 @@ export default class Dropdown extends AutoControlledComponent<
       e: React.SyntheticEvent,
       searchInputProps: DropdownSearchInputProps,
     ) => {
-      if (keyboardKey.getCode(e) === keyboardKey.Tab && _.isNil(highlightedIndex)) {
+      if (keyboardKey.getCode(e) === keyboardKey.Tab && !_.isNil(highlightedIndex)) {
         selectItemAtIndex(highlightedIndex)
       }
 
diff --git a/src/components/Dropdown/DropdownSearchInput.tsx b/src/components/Dropdown/DropdownSearchInput.tsx
index 6a4a4db94c..a6ed33276a 100644
--- a/src/components/Dropdown/DropdownSearchInput.tsx
+++ b/src/components/Dropdown/DropdownSearchInput.tsx
@@ -8,6 +8,8 @@ import { UIComponentProps } from '../../lib/commonPropInterfaces'
 import Input from '../Input/Input'
 
 export interface DropdownSearchInputProps extends UIComponentProps<DropdownSearchInputProps> {
+  /** Informs the search input about an existing toggle button. */
+  hasToggleButton?: boolean
   /**
    * Ref callback with an input DOM node.
    *
@@ -68,6 +70,7 @@ class DropdownSearchInput extends UIComponent<ReactProps<DropdownSearchInputProp
     }),
     accessibilityInputProps: PropTypes.object,
     accessibilityComboboxProps: PropTypes.object,
+    hasToggleButton: PropTypes.bool,
     inputRef: PropTypes.func,
     onFocus: PropTypes.func,
     onInputBlur: PropTypes.func,
diff --git a/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts b/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
index e8a04e5c22..bd496b3eb2 100644
--- a/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
@@ -16,9 +16,15 @@ const dropdownSearchInputStyles: ComponentSlotStylesInput<
     },
   }),
 
-  combobox: ({ variables: { comboboxFlexBasis } }): ICSSInJSStyle => ({
+  combobox: ({
+    variables: { comboboxFlexBasis, toggleButtonSize },
+    props: { hasToggleButton },
+  }): ICSSInJSStyle => ({
     flexBasis: comboboxFlexBasis,
     flexGrow: 1,
+    ...(hasToggleButton && {
+      paddingRight: toggleButtonSize,
+    }),
   }),
 }
 
diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index 446b22fb4a..fbf29496cf 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -7,7 +7,7 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
   root: (): ICSSInJSStyle => ({}),
 
   container: ({
-    props: { focused, toggleButton, fluid },
+    props: { focused, fluid },
     variables: {
       backgroundColor,
       borderBottom,
@@ -16,7 +16,6 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
       borderColorFocus,
       borderRadiusFocus,
       color,
-      toggleButtonSize,
       width,
     },
   }): ICSSInJSStyle => ({
@@ -31,9 +30,6 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
     color,
     width: fluid ? '100%' : width,
     position: 'relative',
-    ...(toggleButton && {
-      paddingRight: toggleButtonSize,
-    }),
     ...(focused && {
       borderColor: borderColorFocus,
       borderRadius: borderRadiusFocus,
@@ -85,9 +81,12 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
     position: 'absolute',
     height: toggleButtonSize,
     width: toggleButtonSize,
-    border: 0,
+    cursor: 'pointer',
     backgroundColor: 'transparent',
     margin: 0,
+    display: 'flex',
+    justifyContent: 'center',
+    alignItems: 'center',
     ...(fluid ? { right: 0 } : { left: `calc(${width} - ${toggleButtonSize})` }),
   }),
 }

From 0d7a892b3ed7cd2a68742777a07d295e8494cc28 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 10:39:45 +0200
Subject: [PATCH 18/62] replaced Icon with unicode char for theme consistency

---
 src/components/Dropdown/Dropdown.tsx | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index f3a8f9d6bc..9a4753cb50 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -3,7 +3,11 @@ import * as PropTypes from 'prop-types'
 import * as _ from 'lodash'
 
 import { Extendable, ShorthandValue, ComponentEventHandler } from '../../../types/utils'
-import { ComponentSlotStylesInput, ComponentVariablesInput } from '../../themes/types'
+import {
+  ComponentSlotStylesInput,
+  ComponentVariablesInput,
+  ComponentSlotClasses,
+} from '../../themes/types'
 import Downshift, {
   DownshiftState,
   StateChangeOptions,
@@ -23,7 +27,6 @@ import {
 import keyboardKey from 'keyboard-key'
 import List from '../List/List'
 import Text from '../Text/Text'
-import Icon from '../Icon/Icon'
 import Ref from '../Ref/Ref'
 import { UIComponentProps } from '../../lib/commonPropInterfaces'
 import DropdownItem, { DropdownItemProps } from './DropdownItem'
@@ -256,7 +259,7 @@ export default class Dropdown extends AutoControlledComponent<
                         variables,
                       )
                     : this.renderTriggerButton(styles, getToggleButtonProps)}
-                  {toggleButton && this.renderToggleButton(getToggleButtonProps, styles, isOpen)}
+                  {toggleButton && this.renderToggleButton(getToggleButtonProps, classes, isOpen)}
                   {this.renderItemsList(
                     styles,
                     variables,
@@ -349,19 +352,14 @@ export default class Dropdown extends AutoControlledComponent<
 
   private renderToggleButton(
     getToggleButtonProps: (options?: GetToggleButtonPropsOptions) => any,
-    styles: ComponentSlotStylesInput,
+    classes: ComponentSlotClasses,
     isOpen: boolean,
   ) {
-    const { onClick, onBlur, onKeyDown, onKeyUp } = getToggleButtonProps()
+    const { onClick } = getToggleButtonProps()
     return (
-      <Icon
-        name={`chevron ${isOpen ? 'up' : 'down'}`}
-        styles={styles.toggleButton}
-        onClick={onClick}
-        onBlur={onBlur}
-        onKeyDown={onKeyDown}
-        onKeyUp={onKeyUp}
-      />
+      <span className={classes.toggleButton} onClick={onClick}>
+        {isOpen ? String.fromCharCode(9650) : String.fromCharCode(9660)}
+      </span>
     )
   }
 

From 1bdf7047961e72a8a546fd10e37460c6b750d388 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 11:58:50 +0200
Subject: [PATCH 19/62] some more review comments handled

---
 src/components/Dropdown/Dropdown.tsx | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 9a4753cb50..d8a8395745 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -218,7 +218,8 @@ export default class Dropdown extends AutoControlledComponent<
           inputValue={search ? searchQuery : undefined}
           stateReducer={this.handleDownshiftStateChanges}
           itemToString={itemToString}
-          // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
+          // If it's single search, don't pass anything. Pass a null otherwise, as Downshift does
+          // not handle selection by default for single/multiple selection and multiple search.
           selectedItem={search && !multiple ? undefined : null}
           getA11yStatusMessage={getA11yStatusMessage}
           onStateChange={changes => {
@@ -286,13 +287,7 @@ export default class Dropdown extends AutoControlledComponent<
   ): JSX.Element {
     const { placeholder, itemToString, multiple } = this.props
     const { value } = this.state
-    let content
-
-    if (multiple) {
-      content = placeholder
-    } else {
-      content = value ? itemToString(value) : placeholder
-    }
+    const content = value && !multiple ? itemToString(value) : placeholder
 
     return (
       <Ref innerRef={this.buttonRef}>

From 518dad57ef810368ba4c6572f3d034c2f2b11451 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 12:40:08 +0200
Subject: [PATCH 20/62] some more code improvements in Dropdown

---
 src/components/Dropdown/Dropdown.tsx | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index d8a8395745..83afe6b3c9 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -29,7 +29,7 @@ import List from '../List/List'
 import Text from '../Text/Text'
 import Ref from '../Ref/Ref'
 import { UIComponentProps } from '../../lib/commonPropInterfaces'
-import DropdownItem, { DropdownItemProps } from './DropdownItem'
+import DropdownItem from './DropdownItem'
 import DropdownLabel, { DropdownLabelProps } from './DropdownLabel'
 import DropdownSearchInput, { DropdownSearchInputProps } from './DropdownSearchInput'
 import Button from '../Button/Button'
@@ -239,11 +239,10 @@ export default class Dropdown extends AutoControlledComponent<
             highlightedIndex,
             selectItemAtIndex,
           }) => {
-            const accessibilityRootProps = getRootProps(
+            const { innerRef, ...accessibilityRootPropsRest } = getRootProps(
               { refKey: 'innerRef' },
               { suppressRefError: true },
             )
-            const { innerRef, ...accessibilityRootPropsRest } = accessibilityRootProps
             return (
               <Ref innerRef={innerRef}>
                 <div
@@ -369,9 +368,8 @@ export default class Dropdown extends AutoControlledComponent<
     getItemProps: (options: GetItemPropsOptions<ShorthandValue>) => any,
     getInputProps: (options?: GetInputPropsOptions) => any,
   ) {
-    const accessibilityMenuProps = {
-      ...getMenuProps({ refKey: 'innerRef' }, { suppressRefError: true }),
-    }
+    const accessibilityMenuProps = getMenuProps({ refKey: 'innerRef' }, { suppressRefError: true })
+    // If it's just a selection, some attributes and listeners from Downshift input need to go on the menu list.
     if (!this.props.search) {
       const accessibilityInputProps = getInputProps()
       accessibilityMenuProps['aria-activedescendant'] =
@@ -387,7 +385,6 @@ export default class Dropdown extends AutoControlledComponent<
       }
     }
     const { innerRef, ...accessibilityMenuPropsRest } = accessibilityMenuProps
-
     return (
       <Ref
         innerRef={(listNode: HTMLElement) => {
@@ -426,8 +423,7 @@ export default class Dropdown extends AutoControlledComponent<
                 key: (item as any).header,
               }),
           },
-          overrideProps: (predefinedProps: DropdownItemProps) =>
-            this.handleItemOverrides(item, index, getItemProps),
+          overrideProps: () => this.handleItemOverrides(item, index, getItemProps),
         })
       })
     }

From 3cdc8d8634ebb299ec9aa3e53f7807b5203c4ce2 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 12:40:28 +0200
Subject: [PATCH 21/62] replaced right margin with padding for combobox

---
 .../teams/components/Dropdown/dropdownSearchInputStyles.ts      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts b/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
index bd496b3eb2..16c52581ff 100644
--- a/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
@@ -23,7 +23,7 @@ const dropdownSearchInputStyles: ComponentSlotStylesInput<
     flexBasis: comboboxFlexBasis,
     flexGrow: 1,
     ...(hasToggleButton && {
-      paddingRight: toggleButtonSize,
+      marginRight: toggleButtonSize,
     }),
   }),
 }

From bb670f98e67beccf3719a41e5dbb10e5692f6b77 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 12:59:42 +0200
Subject: [PATCH 22/62] used functional components in the examples

---
 ...ropdownExampleMultipleSearch.shorthand.tsx | 26 +++++++----------
 ...opdownExampleSingleSelection.shorthand.tsx | 24 +++++++--------
 ...wnExampleMultipleSearchFluid.shorthand.tsx | 29 ++++++++-----------
 ...ultipleSearchImageAndContent.shorthand.tsx | 26 +++++++----------
 ...leMultipleSearchToggleButton.shorthand.tsx | 28 ++++++++----------
 5 files changed, 56 insertions(+), 77 deletions(-)

diff --git a/docs/src/examples/components/Dropdown/Types/DropdownExampleMultipleSearch.shorthand.tsx b/docs/src/examples/components/Dropdown/Types/DropdownExampleMultipleSearch.shorthand.tsx
index 4dc983cd0c..6aba57a1d9 100644
--- a/docs/src/examples/components/Dropdown/Types/DropdownExampleMultipleSearch.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Types/DropdownExampleMultipleSearch.shorthand.tsx
@@ -13,21 +13,17 @@ const inputItems = [
   'Selina Kyle',
 ]
 
-class DropdownExample extends React.Component {
-  render() {
-    return (
-      <Dropdown
-        multiple
-        search
-        getA11ySelectionMessage={getA11ySelectionMessage}
-        getA11yStatusMessage={getA11yStatusMessage}
-        noResultsMessage="We couldn't find any matches."
-        placeholder="Start typing a name"
-        items={inputItems}
-      />
-    )
-  }
-}
+const DropdownExample = () => (
+  <Dropdown
+    multiple
+    search
+    getA11ySelectionMessage={getA11ySelectionMessage}
+    getA11yStatusMessage={getA11yStatusMessage}
+    noResultsMessage="We couldn't find any matches."
+    placeholder="Start typing a name"
+    items={inputItems}
+  />
+)
 
 const getA11ySelectionMessage = {
   onAdd: item => `${item} has been selected.`,
diff --git a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
index 1145fb1b6c..c4f046d982 100644
--- a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
@@ -13,20 +13,16 @@ const inputItems = [
   'Selina Kyle',
 ]
 
-class DropdownExample extends React.Component {
-  render() {
-    return (
-      <Dropdown
-        getA11yStatusMessage={getA11yStatusMessage}
-        getA11ySelectionMessage={{
-          onAdd: item => `${item} has been selected.`,
-        }}
-        placeholder="Select your hero"
-        items={inputItems}
-      />
-    )
-  }
-}
+const DropdownExample = () => (
+  <Dropdown
+    getA11yStatusMessage={getA11yStatusMessage}
+    getA11ySelectionMessage={{
+      onAdd: item => `${item} has been selected.`,
+    }}
+    placeholder="Select your hero"
+    items={inputItems}
+  />
+)
 
 const getA11yStatusMessage = ({
   isOpen,
diff --git a/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchFluid.shorthand.tsx b/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchFluid.shorthand.tsx
index 7dd60f245a..5d1de96419 100644
--- a/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchFluid.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchFluid.shorthand.tsx
@@ -12,23 +12,18 @@ const inputItems = [
   'Peter Parker',
   'Selina Kyle',
 ]
-
-class DropdownExample extends React.Component {
-  render() {
-    return (
-      <Dropdown
-        multiple
-        getA11ySelectionMessage={getA11ySelectionMessage}
-        getA11yStatusMessage={getA11yStatusMessage}
-        noResultsMessage="We couldn't find any matches."
-        search
-        fluid
-        placeholder="Start typing a name"
-        items={inputItems}
-      />
-    )
-  }
-}
+const DropdownExample = () => (
+  <Dropdown
+    multiple
+    getA11ySelectionMessage={getA11ySelectionMessage}
+    getA11yStatusMessage={getA11yStatusMessage}
+    noResultsMessage="We couldn't find any matches."
+    search
+    fluid
+    placeholder="Start typing a name"
+    items={inputItems}
+  />
+)
 
 const getA11ySelectionMessage = {
   onAdd: item => `${item} has been selected.`,
diff --git a/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchImageAndContent.shorthand.tsx b/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchImageAndContent.shorthand.tsx
index ed52d80f56..248055b67a 100644
--- a/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchImageAndContent.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchImageAndContent.shorthand.tsx
@@ -49,21 +49,17 @@ const inputItems = [
   },
 ]
 
-class DropdownExample extends React.Component {
-  render() {
-    return (
-      <Dropdown
-        multiple
-        getA11yStatusMessage={getA11yStatusMessage}
-        search
-        getA11ySelectionMessage={getA11ySelectionMessage}
-        noResultsMessage="We couldn't find any matches."
-        placeholder="Start typing a name"
-        items={inputItems}
-      />
-    )
-  }
-}
+const DropdownExample = () => (
+  <Dropdown
+    multiple
+    getA11yStatusMessage={getA11yStatusMessage}
+    search
+    getA11ySelectionMessage={getA11ySelectionMessage}
+    noResultsMessage="We couldn't find any matches."
+    placeholder="Start typing a name"
+    items={inputItems}
+  />
+)
 
 const getA11ySelectionMessage = {
   onAdd: item => `${item.header} has been selected.`,
diff --git a/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchToggleButton.shorthand.tsx b/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchToggleButton.shorthand.tsx
index 1f85c9cc1b..3fb6470421 100644
--- a/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchToggleButton.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchToggleButton.shorthand.tsx
@@ -13,22 +13,18 @@ const inputItems = [
   'Selina Kyle',
 ]
 
-class DropdownExample extends React.Component {
-  render() {
-    return (
-      <Dropdown
-        multiple
-        getA11yStatusMessage={getA11yStatusMessage}
-        getA11ySelectionMessage={getA11ySelectionMessage}
-        noResultsMessage="We couldn't find any matches."
-        search
-        placeholder="Start typing a name"
-        toggleButton
-        items={inputItems}
-      />
-    )
-  }
-}
+const DropdownExample = () => (
+  <Dropdown
+    multiple
+    getA11yStatusMessage={getA11yStatusMessage}
+    getA11ySelectionMessage={getA11ySelectionMessage}
+    noResultsMessage="We couldn't find any matches."
+    search
+    placeholder="Start typing a name"
+    toggleButton
+    items={inputItems}
+  />
+)
 
 const getA11ySelectionMessage = {
   onAdd: item => `${item} has been selected.`,

From c851c132061f779b5ec3385c5c0743d015660b11 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 13:11:15 +0200
Subject: [PATCH 23/62] overriding downshift aria label for the toggle button

---
 src/components/Dropdown/Dropdown.tsx | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 83afe6b3c9..1ac2100cae 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -301,6 +301,7 @@ export default class Dropdown extends AutoControlledComponent<
             onBlur: () => {
               this.setState({ focused: false })
             },
+            'aria-label': content,
           })}
         />
       </Ref>

From 58c41a8ead6d83191832f11229522faa6ea23782 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 13:21:45 +0200
Subject: [PATCH 24/62] made the toggle button arrow non-selectable

---
 src/themes/teams/components/Dropdown/dropdownStyles.ts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index fbf29496cf..a69d19057d 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -87,6 +87,7 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
     display: 'flex',
     justifyContent: 'center',
     alignItems: 'center',
+    userSelect: 'none',
     ...(fluid ? { right: 0 } : { left: `calc(${width} - ${toggleButtonSize})` }),
   }),
 }

From 96a61ab708f3aaeae5b1b2ec8481e3b2f63f37ee Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 15:29:51 +0200
Subject: [PATCH 25/62] used a lodash util instead of filter

---
 src/components/Dropdown/Dropdown.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 1ac2100cae..46dfe032b6 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -498,7 +498,7 @@ export default class Dropdown extends AutoControlledComponent<
     let filteredItems = items
 
     if (multiple) {
-      filteredItems = filteredItems.filter(item => (value as ShorthandValue[]).indexOf(item) === -1)
+      filteredItems = _.difference(filteredItems, value as ShorthandValue[])
     }
     if (search) {
       if (_.isFunction(search)) {

From 97758c282ca0a694a08a7a913e2bdfe608950f95 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Fri, 4 Jan 2019 10:59:52 +0200
Subject: [PATCH 26/62] used buttonNode for consistency

---
 src/components/Dropdown/Dropdown.tsx | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 46dfe032b6..6acfd8c61c 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -133,9 +133,9 @@ export default class Dropdown extends AutoControlledComponent<
   Extendable<DropdownProps>,
   DropdownState
 > {
+  private buttonNode: HTMLElement
   private inputNode: HTMLElement
   private listNode: HTMLElement
-  private buttonRef = React.createRef<HTMLElement>()
 
   static displayName = 'Dropdown'
 
@@ -289,7 +289,11 @@ export default class Dropdown extends AutoControlledComponent<
     const content = value && !multiple ? itemToString(value) : placeholder
 
     return (
-      <Ref innerRef={this.buttonRef}>
+      <Ref
+        innerRef={(buttonNode: HTMLElement) => {
+          this.buttonNode = buttonNode
+        }}
+      >
         <Button
           content={content}
           fluid
@@ -664,7 +668,7 @@ export default class Dropdown extends AutoControlledComponent<
         return
       case keyboardKey.Escape:
         accessibilityInputPropsKeyDown(e)
-        this.buttonRef.current.focus()
+        this.buttonNode.focus()
         return
       default:
         accessibilityInputPropsKeyDown(e)
@@ -684,7 +688,7 @@ export default class Dropdown extends AutoControlledComponent<
       this.setA11yStatus(getA11ySelectionMessage.onAdd(item))
     }
     if (!search) {
-      this.buttonRef.current.focus()
+      this.buttonNode.focus()
     }
 
     // we don't have event for it, but want to keep the event handling interface, event is empty.

From c28f7c57cbdb5f7bd53ff175be20098e85c473cb Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Fri, 4 Jan 2019 11:22:35 +0200
Subject: [PATCH 27/62] apply tabIndex only if dropdown is non-search

---
 src/components/Dropdown/Dropdown.tsx | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 6acfd8c61c..7c8843bda4 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -374,8 +374,9 @@ export default class Dropdown extends AutoControlledComponent<
     getInputProps: (options?: GetInputPropsOptions) => any,
   ) {
     const accessibilityMenuProps = getMenuProps({ refKey: 'innerRef' }, { suppressRefError: true })
+    const { search } = this.props
     // If it's just a selection, some attributes and listeners from Downshift input need to go on the menu list.
-    if (!this.props.search) {
+    if (!search) {
       const accessibilityInputProps = getInputProps()
       accessibilityMenuProps['aria-activedescendant'] =
         accessibilityInputProps['aria-activedescendant']
@@ -400,7 +401,7 @@ export default class Dropdown extends AutoControlledComponent<
         <List
           {...accessibilityMenuPropsRest}
           styles={styles.list}
-          tabIndex={-1}
+          tabIndex={search ? undefined : -1} // needs to be focused when trigger button is activated.
           aria-hidden={!isOpen}
           items={isOpen ? this.renderItems(styles, variables, getItemProps, highlightedIndex) : []}
         />

From 1563a6551ed04f116c78d0d649ebc39b66546e1e Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Fri, 4 Jan 2019 11:23:19 +0200
Subject: [PATCH 28/62] Revert "used buttonNode for consistency"

This reverts commit 97758c282ca0a694a08a7a913e2bdfe608950f95.
---
 src/components/Dropdown/Dropdown.tsx | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 7c8843bda4..83d6967feb 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -133,9 +133,9 @@ export default class Dropdown extends AutoControlledComponent<
   Extendable<DropdownProps>,
   DropdownState
 > {
-  private buttonNode: HTMLElement
   private inputNode: HTMLElement
   private listNode: HTMLElement
+  private buttonRef = React.createRef<HTMLElement>()
 
   static displayName = 'Dropdown'
 
@@ -289,11 +289,7 @@ export default class Dropdown extends AutoControlledComponent<
     const content = value && !multiple ? itemToString(value) : placeholder
 
     return (
-      <Ref
-        innerRef={(buttonNode: HTMLElement) => {
-          this.buttonNode = buttonNode
-        }}
-      >
+      <Ref innerRef={this.buttonRef}>
         <Button
           content={content}
           fluid
@@ -669,7 +665,7 @@ export default class Dropdown extends AutoControlledComponent<
         return
       case keyboardKey.Escape:
         accessibilityInputPropsKeyDown(e)
-        this.buttonNode.focus()
+        this.buttonRef.current.focus()
         return
       default:
         accessibilityInputPropsKeyDown(e)
@@ -689,7 +685,7 @@ export default class Dropdown extends AutoControlledComponent<
       this.setA11yStatus(getA11ySelectionMessage.onAdd(item))
     }
     if (!search) {
-      this.buttonNode.focus()
+      this.buttonRef.current.focus()
     }
 
     // we don't have event for it, but want to keep the event handling interface, event is empty.

From 5e4dc81e993af85bd8e91c0f2a755cf2aec6d79d Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Fri, 4 Jan 2019 12:51:59 +0200
Subject: [PATCH 29/62] refactored the Refs use in Dropdown

---
 src/components/Dropdown/Dropdown.tsx          | 23 +++++++-------
 .../Dropdown/DropdownSearchInput.tsx          | 24 +++++++--------
 src/components/Input/Input.tsx                | 30 ++++++++-----------
 3 files changed, 35 insertions(+), 42 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 83d6967feb..98b3183ffc 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -23,6 +23,7 @@ import {
   RenderResultConfig,
   customPropTypes,
   commonPropTypes,
+  handleRef,
 } from '../../lib'
 import keyboardKey from 'keyboard-key'
 import List from '../List/List'
@@ -133,9 +134,9 @@ export default class Dropdown extends AutoControlledComponent<
   Extendable<DropdownProps>,
   DropdownState
 > {
-  private inputNode: HTMLElement
-  private listNode: HTMLElement
   private buttonRef = React.createRef<HTMLElement>()
+  private inputRef = React.createRef<HTMLElement>()
+  private listRef = React.createRef<HTMLElement>()
 
   static displayName = 'Dropdown'
 
@@ -224,7 +225,7 @@ export default class Dropdown extends AutoControlledComponent<
           getA11yStatusMessage={getA11yStatusMessage}
           onStateChange={changes => {
             if (changes.isOpen && !search) {
-              this.listNode.focus()
+              this.listRef.current.focus()
             }
           }}
         >
@@ -330,9 +331,7 @@ export default class Dropdown extends AutoControlledComponent<
         placeholder: noPlaceholder ? '' : placeholder,
         hasToggleButton: !!toggleButton,
         variables,
-        inputRef: (inputNode: HTMLElement) => {
-          this.inputNode = inputNode
-        },
+        inputRef: this.inputRef,
       },
       overrideProps: (predefinedProps: DropdownSearchInputProps) =>
         this.handleSearchInputOverrides(
@@ -389,9 +388,9 @@ export default class Dropdown extends AutoControlledComponent<
     const { innerRef, ...accessibilityMenuPropsRest } = accessibilityMenuProps
     return (
       <Ref
-        innerRef={(listNode: HTMLElement) => {
-          this.listNode = listNode
-          innerRef(listNode)
+        innerRef={(listElement: HTMLElement) => {
+          handleRef(this.listRef, listElement)
+          handleRef(innerRef, listElement)
         }}
       >
         <List
@@ -485,7 +484,7 @@ export default class Dropdown extends AutoControlledComponent<
       case Downshift.stateChangeTypes.blurButton:
         // Downshift closes the list by default on trigger blur. It does not support the case when dropdown is
         // single selection and focuses list on trigger click/up/down/space/enter. Treating that here.
-        if (state.isOpen && document.activeElement === this.listNode) {
+        if (state.isOpen && document.activeElement === this.listRef.current) {
           return {} // won't change state in this case.
         }
       default:
@@ -645,7 +644,7 @@ export default class Dropdown extends AutoControlledComponent<
   }
 
   private handleContainerClick = (isOpen: boolean) => {
-    !isOpen && this.inputNode.focus()
+    !isOpen && this.inputRef.current.focus()
   }
 
   private handleListKeyDown = (
@@ -694,7 +693,7 @@ export default class Dropdown extends AutoControlledComponent<
 
   private handleSelectedItemRemove(e: React.SyntheticEvent, item: ShorthandValue) {
     this.removeItemFromValue(item)
-    this.inputNode.focus()
+    this.inputRef.current.focus()
     e.stopPropagation()
   }
 
diff --git a/src/components/Dropdown/DropdownSearchInput.tsx b/src/components/Dropdown/DropdownSearchInput.tsx
index a6ed33276a..5d967a245d 100644
--- a/src/components/Dropdown/DropdownSearchInput.tsx
+++ b/src/components/Dropdown/DropdownSearchInput.tsx
@@ -10,12 +10,9 @@ import Input from '../Input/Input'
 export interface DropdownSearchInputProps extends UIComponentProps<DropdownSearchInputProps> {
   /** Informs the search input about an existing toggle button. */
   hasToggleButton?: boolean
-  /**
-   * Ref callback with an input DOM node.
-   *
-   * @param {JSX.Element} node - input DOM node.
-   */
-  inputRef?: (inputNode: HTMLElement) => void
+
+  /** Ref for input DOM node. */
+  inputRef?: React.Ref<HTMLElement>
 
   /**
    * Called on input element focus.
@@ -71,7 +68,7 @@ class DropdownSearchInput extends UIComponent<ReactProps<DropdownSearchInputProp
     accessibilityInputProps: PropTypes.object,
     accessibilityComboboxProps: PropTypes.object,
     hasToggleButton: PropTypes.bool,
-    inputRef: PropTypes.func,
+    inputRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
     onFocus: PropTypes.func,
     onInputBlur: PropTypes.func,
     onInputKeyDown: PropTypes.func,
@@ -79,10 +76,6 @@ class DropdownSearchInput extends UIComponent<ReactProps<DropdownSearchInputProp
     placeholder: PropTypes.string,
   }
 
-  private handleInputRef = (inputNode: HTMLElement) => {
-    _.invoke(this.props, 'inputRef', inputNode)
-  }
-
   private handleFocus = (e: React.SyntheticEvent) => {
     _.invoke(this.props, 'onFocus', e, this.props)
   }
@@ -100,10 +93,15 @@ class DropdownSearchInput extends UIComponent<ReactProps<DropdownSearchInputProp
   }
 
   public renderComponent({ rest, styles }: RenderResultConfig<DropdownSearchInputProps>) {
-    const { accessibilityComboboxProps, accessibilityInputProps, placeholder } = this.props
+    const {
+      accessibilityComboboxProps,
+      accessibilityInputProps,
+      inputRef,
+      placeholder,
+    } = this.props
     return (
       <Input
-        inputRef={this.handleInputRef}
+        inputRef={inputRef}
         onFocus={this.handleFocus}
         onKeyUp={this.handleKeyUp}
         wrapper={{
diff --git a/src/components/Input/Input.tsx b/src/components/Input/Input.tsx
index 8eee55fa30..73da8e5f84 100644
--- a/src/components/Input/Input.tsx
+++ b/src/components/Input/Input.tsx
@@ -11,6 +11,7 @@ import {
   UIComponentProps,
   ChildrenComponentProps,
   commonPropTypes,
+  handleRef,
 } from '../../lib'
 import { ReactProps, ShorthandValue, ComponentEventHandler } from '../../../types/utils'
 import Icon from '../Icon/Icon'
@@ -50,12 +51,8 @@ export interface InputProps extends UIComponentProps, ChildrenComponentProps {
   /** The HTML input type. */
   type?: string
 
-  /**
-   * Ref callback with an input DOM node.
-   *
-   * @param {JSX.Element} node - input DOM node.
-   */
-  inputRef?: (node: HTMLElement) => void
+  /** Ref for input DOM node. */
+  inputRef?: React.Ref<HTMLElement>
 
   /** The value of the input. */
   value?: React.ReactText
@@ -77,7 +74,7 @@ export interface InputState {
  *  - if input is search, then use "role='search'"
  */
 class Input extends AutoControlledComponent<ReactProps<InputProps>, InputState> {
-  private inputDomElement: HTMLInputElement
+  private inputRef = React.createRef<HTMLElement>()
 
   static className = 'ui-input'
 
@@ -93,7 +90,7 @@ class Input extends AutoControlledComponent<ReactProps<InputProps>, InputState>
     icon: customPropTypes.itemShorthand,
     iconPosition: PropTypes.oneOf(['start', 'end']),
     input: customPropTypes.itemShorthand,
-    inputRef: PropTypes.func,
+    inputRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
     inline: PropTypes.bool,
     onChange: PropTypes.func,
     type: PropTypes.string,
@@ -116,7 +113,7 @@ class Input extends AutoControlledComponent<ReactProps<InputProps>, InputState>
     styles,
     variables,
   }: RenderResultConfig<InputProps>) {
-    const { className, input, type, wrapper } = this.props
+    const { className, input, inputRef, type, wrapper } = this.props
     const { value = '' } = this.state
     const [htmlInputProps, rest] = partitionHTMLProps(restProps)
 
@@ -125,7 +122,12 @@ class Input extends AutoControlledComponent<ReactProps<InputProps>, InputState>
         className: cx(Input.className, className),
         children: (
           <>
-            <Ref innerRef={this.handleInputRef}>
+            <Ref
+              innerRef={(inputElement: HTMLElement) => {
+                handleRef(this.inputRef, inputElement)
+                handleRef(inputRef, inputElement)
+              }}
+            >
               {Slot.create(input || type, {
                 defaultProps: {
                   ...htmlInputProps,
@@ -155,16 +157,10 @@ class Input extends AutoControlledComponent<ReactProps<InputProps>, InputState>
     })
   }
 
-  private handleInputRef = (inputNode: HTMLElement) => {
-    this.inputDomElement = inputNode as HTMLInputElement
-
-    _.invoke(this.props, 'inputRef', inputNode)
-  }
-
   private handleIconOverrides = predefinedProps => ({
     onClick: (e: React.SyntheticEvent) => {
       this.handleOnClear()
-      this.inputDomElement.focus()
+      this.inputRef.current.focus()
       _.invoke(predefinedProps, 'onClick', e, this.props)
     },
     ...(predefinedProps.onClick && { tabIndex: '0' }),

From 14532ef60093b65e9d8958f5130311969d11981d Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Mon, 10 Dec 2018 13:17:22 +0200
Subject: [PATCH 30/62] crude implementation

---
 ...opdownExampleSingleSelection.shorthand.tsx | 50 +++++++++++++++++++
 .../components/Dropdown/Types/index.tsx       |  5 ++
 src/components/Dropdown/Dropdown.tsx          | 48 ++++++++++++++----
 .../components/Dropdown/dropdownStyles.ts     | 16 ++++++
 4 files changed, 109 insertions(+), 10 deletions(-)
 create mode 100644 docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx

diff --git a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
new file mode 100644
index 0000000000..e6968e8313
--- /dev/null
+++ b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
@@ -0,0 +1,50 @@
+import * as React from 'react'
+import { Dropdown } from '@stardust-ui/react'
+
+const inputItems = [
+  'Bruce Wayne',
+  'Natasha Romanoff',
+  'Steven Strange',
+  'Alfred Pennyworth',
+  `Scarlett O'Hara`,
+  'Imperator Furiosa',
+  'Bruce Banner',
+  'Peter Parker',
+  'Selina Kyle',
+]
+
+class DropdownExample extends React.Component {
+  render() {
+    return (
+      <Dropdown
+        getA11yStatusMessage={getA11yStatusMessage}
+        noResultsMessage="We couldn't find any matches."
+        placeholder="Start typing a name"
+        items={inputItems}
+      />
+    )
+  }
+}
+
+const getA11yStatusMessage = ({
+  isOpen,
+  itemToString,
+  previousResultCount,
+  resultCount,
+  selectedItem,
+}) => {
+  if (!isOpen) {
+    return selectedItem ? itemToString(selectedItem) : ''
+  }
+  if (!resultCount) {
+    return 'No results are available.'
+  }
+  if (resultCount !== previousResultCount) {
+    return `${resultCount} result${
+      resultCount === 1 ? ' is' : 's are'
+    } available, use up and down arrow keys to navigate. Press Enter key to select.`
+  }
+  return ''
+}
+
+export default DropdownExample
diff --git a/docs/src/examples/components/Dropdown/Types/index.tsx b/docs/src/examples/components/Dropdown/Types/index.tsx
index 6a93a98f50..dc2a7499ef 100644
--- a/docs/src/examples/components/Dropdown/Types/index.tsx
+++ b/docs/src/examples/components/Dropdown/Types/index.tsx
@@ -4,6 +4,11 @@ import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'
 
 const Types = () => (
   <ExampleSection title="Types">
+    <ComponentExample
+      title="Single Selection"
+      description="A dropdown with single selection."
+      examplePath="components/Dropdown/Types/DropdownExampleSingleSelection.shorthand"
+    />
     <ComponentExample
       title="Multiple Search"
       description="A dropdown with multiple selection and search."
diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index bb7aded10a..e302fb9a49 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -30,6 +30,7 @@ import DropdownItem, { DropdownItemProps } from './DropdownItem'
 import DropdownLabel, { DropdownLabelProps } from './DropdownLabel'
 import DropdownSearchInput from './DropdownSearchInput'
 import { DropdownSearchInputProps } from 'semantic-ui-react'
+import Button from '../Button/Button'
 
 // TODO: To be replaced when Downshift will add highlightedItem in their interface.
 export interface A11yStatusMessageOptions<Item> extends DownshiftA11yStatusMessageOptions<Item> {
@@ -210,11 +211,11 @@ export default class Dropdown extends AutoControlledComponent<
       <ElementType className={classes.root} {...rest}>
         <Downshift
           onChange={this.handleSelectedChange}
-          inputValue={searchQuery}
+          inputValue={search ? searchQuery : undefined}
           stateReducer={this.handleDownshiftStateChanges}
           itemToString={itemToString}
           // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
-          selectedItem={multiple ? null : undefined}
+          selectedItem={search && !multiple ? undefined : null}
           getA11yStatusMessage={getA11yStatusMessage}
         >
           {({
@@ -233,13 +234,14 @@ export default class Dropdown extends AutoControlledComponent<
                 onClick={this.handleContainerClick.bind(this, isOpen)}
               >
                 {multiple && this.renderSelectedItems(styles)}
-                {search &&
-                  this.renderSearchInput(
-                    getRootProps,
-                    getInputProps,
-                    highlightedIndex,
-                    selectItemAtIndex,
-                  )}
+                {search
+                  ? this.renderSearchInput(
+                      getRootProps,
+                      getInputProps,
+                      highlightedIndex,
+                      selectItemAtIndex,
+                    )
+                  : this.renderTriggerButton(getToggleButtonProps, styles)}
                 {toggleButton && this.renderToggleButton(getToggleButtonProps, styles, isOpen)}
                 {this.renderItemsList(
                   styles,
@@ -257,6 +259,32 @@ export default class Dropdown extends AutoControlledComponent<
     )
   }
 
+  private renderTriggerButton(
+    getToggleButtonProps: (options?: GetToggleButtonPropsOptions) => any,
+    styles: ComponentSlotStylesInput,
+  ): JSX.Element {
+    const { placeholder, itemToString } = this.props
+    const { value } = this.state
+    return (
+      <Button
+        content={value ? itemToString(value) : placeholder}
+        fluid
+        styles={styles.button}
+        {...getToggleButtonProps({
+          onFocus: () => {
+            this.setState({ focused: true })
+          },
+          onBlur: () => {
+            this.setState({ focused: false })
+          },
+          onClick: e => {
+            e.stopPropagation()
+          },
+        })}
+      />
+    )
+  }
+
   private renderSearchInput(
     getRootProps: (options?: GetMenuPropsOptions, otherOptions?: GetPropsCommonOptions) => any,
     getInputProps: (options?: GetInputPropsOptions) => any,
@@ -611,7 +639,7 @@ export default class Dropdown extends AutoControlledComponent<
       value,
     })
     if (getA11ySelectionMessage && getA11ySelectionMessage.onRemove) {
-      this.setA11yStatus(getA11ySelectionMessage.onRemove(item))
+      this.setA11yStatus(getA11ySelectionMessage.onRemove(poppedItem))
     }
 
     // we don't have event for it, but want to keep the event handling interface, event is empty.
diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index 62436c7499..5a2120e940 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -37,6 +37,22 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
     }),
   }),
 
+  button: (): ICSSInJSStyle => {
+    const transparentColorStyle = {
+      backgroundColor: 'transparent',
+      borderColor: 'transparent',
+    }
+    return {
+      boxShadow: '0 0 0 0',
+      margin: '0',
+      justifyContent: 'left',
+      ...transparentColorStyle,
+      ':hover': transparentColorStyle,
+      ':focus': transparentColorStyle,
+      ':active': transparentColorStyle,
+    }
+  },
+
   label: (): ICSSInJSStyle => ({
     margin: '.4rem 0 0 .4rem',
   }),

From 7e870fe38b24d4f6b731ea7a77bbdeec6c09d44d Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Tue, 11 Dec 2018 12:14:28 +0200
Subject: [PATCH 31/62] fixed the toggle and added/refactored styles

---
 ...opdownExampleSingleSelection.shorthand.tsx |  3 +-
 src/components/Dropdown/Dropdown.tsx          | 80 ++++++++++---------
 .../Dropdown/DropdownSearchInput.tsx          | 44 +++++-----
 .../components/Dropdown/dropdownItemStyles.ts |  4 +-
 .../Dropdown/dropdownSearchInputStyles.ts     |  7 +-
 .../components/Dropdown/dropdownStyles.ts     | 38 +++++----
 .../components/Dropdown/dropdownVariables.ts  | 45 ++++++-----
 7 files changed, 116 insertions(+), 105 deletions(-)

diff --git a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
index e6968e8313..1094c540a4 100644
--- a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
@@ -18,8 +18,7 @@ class DropdownExample extends React.Component {
     return (
       <Dropdown
         getA11yStatusMessage={getA11yStatusMessage}
-        noResultsMessage="We couldn't find any matches."
-        placeholder="Start typing a name"
+        placeholder="Select your hero"
         items={inputItems}
       />
     )
diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index e302fb9a49..ef90f67ca4 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -208,38 +208,46 @@ export default class Dropdown extends AutoControlledComponent<
     const { searchQuery } = this.state
 
     return (
-      <ElementType className={classes.root} {...rest}>
-        <Downshift
-          onChange={this.handleSelectedChange}
-          inputValue={search ? searchQuery : undefined}
-          stateReducer={this.handleDownshiftStateChanges}
-          itemToString={itemToString}
-          // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
-          selectedItem={search && !multiple ? undefined : null}
-          getA11yStatusMessage={getA11yStatusMessage}
-        >
-          {({
-            getInputProps,
-            getItemProps,
-            getMenuProps,
-            getRootProps,
-            getToggleButtonProps,
-            isOpen,
-            highlightedIndex,
-            selectItemAtIndex,
-          }) => {
-            return (
-              <div
-                className={classes.containerDiv}
-                onClick={this.handleContainerClick.bind(this, isOpen)}
+      <Downshift
+        onChange={this.handleSelectedChange}
+        inputValue={search ? searchQuery : undefined}
+        stateReducer={this.handleDownshiftStateChanges}
+        itemToString={itemToString}
+        // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
+        selectedItem={search && !multiple ? undefined : null}
+        getA11yStatusMessage={getA11yStatusMessage}
+      >
+        {({
+          getInputProps,
+          getItemProps,
+          getMenuProps,
+          getRootProps,
+          getToggleButtonProps,
+          isOpen,
+          highlightedIndex,
+          selectItemAtIndex,
+        }) => {
+          const accessibilityRootProps = getRootProps(
+            { refKey: 'innerRef' },
+            { suppressRefError: true },
+          )
+          // const getExpandedRootProps = () => rootAccessibilityProps
+          const { innerRef, ...accessibilityRootPropsRest } = accessibilityRootProps
+          return (
+            <Ref innerRef={innerRef}>
+              <ElementType
+                className={classes.root}
+                onClick={multiple ? this.handleContainerClick.bind(this, isOpen) : undefined}
+                {...rest}
               >
                 {multiple && this.renderSelectedItems(styles)}
                 {search
                   ? this.renderSearchInput(
-                      getRootProps,
+                      accessibilityRootPropsRest,
                       getInputProps,
                       highlightedIndex,
                       selectItemAtIndex,
+                      variables,
                     )
                   : this.renderTriggerButton(getToggleButtonProps, styles)}
                 {toggleButton && this.renderToggleButton(getToggleButtonProps, styles, isOpen)}
@@ -251,11 +259,11 @@ export default class Dropdown extends AutoControlledComponent<
                   isOpen,
                   highlightedIndex,
                 )}
-              </div>
-            )
-          }}
-        </Downshift>
-      </ElementType>
+              </ElementType>
+            </Ref>
+          )
+        }}
+      </Downshift>
     )
   }
 
@@ -286,7 +294,7 @@ export default class Dropdown extends AutoControlledComponent<
   }
 
   private renderSearchInput(
-    getRootProps: (options?: GetMenuPropsOptions, otherOptions?: GetPropsCommonOptions) => any,
+    accessibilityComboboxProps: Object,
     getInputProps: (options?: GetInputPropsOptions) => any,
     highlightedIndex: number,
     selectItemAtIndex: (
@@ -294,6 +302,7 @@ export default class Dropdown extends AutoControlledComponent<
       otherStateToSet?: Partial<StateChangeOptions<any>>,
       cb?: () => void,
     ) => void,
+    variables,
   ): JSX.Element {
     const { searchInput, multiple, placeholder } = this.props
     const { searchQuery, value } = this.state
@@ -304,6 +313,7 @@ export default class Dropdown extends AutoControlledComponent<
     return DropdownSearchInput.create(searchInput || {}, {
       defaultProps: {
         placeholder: noPlaceholder ? '' : placeholder,
+        variables,
         inputRef: (inputNode: HTMLElement) => {
           this.inputNode = inputNode
         },
@@ -313,7 +323,7 @@ export default class Dropdown extends AutoControlledComponent<
           predefinedProps,
           highlightedIndex,
           selectItemAtIndex,
-          getRootProps,
+          accessibilityComboboxProps,
           getInputProps,
         ),
     })
@@ -524,7 +534,7 @@ export default class Dropdown extends AutoControlledComponent<
       otherStateToSet?: Partial<StateChangeOptions<any>>,
       cb?: () => void,
     ) => void,
-    getRootProps: (options?: GetMenuPropsOptions, otherOptions?: GetPropsCommonOptions) => any,
+    accessibilityComboboxProps: Object,
     getInputProps: (options?: GetInputPropsOptions) => any,
   ) => {
     const handleInputBlur = (
@@ -564,9 +574,7 @@ export default class Dropdown extends AutoControlledComponent<
         }),
       },
       // same story as above for getRootProps.
-      accessibilityWrapperProps: {
-        ...getRootProps({ refKey: 'innerRef' }, { suppressRefError: true }),
-      },
+      accessibilityComboboxProps,
       onFocus: (e: React.SyntheticEvent, searchInputProps: DropdownSearchInputProps) => {
         this.setState({ focused: true })
 
diff --git a/src/components/Dropdown/DropdownSearchInput.tsx b/src/components/Dropdown/DropdownSearchInput.tsx
index 63cec50f1d..6a4a4db94c 100644
--- a/src/components/Dropdown/DropdownSearchInput.tsx
+++ b/src/components/Dropdown/DropdownSearchInput.tsx
@@ -6,7 +6,6 @@ import { UIComponent, RenderResultConfig, createShorthandFactory, commonPropType
 import { ComponentEventHandler, ReactProps } from '../../../types/utils'
 import { UIComponentProps } from '../../lib/commonPropInterfaces'
 import Input from '../Input/Input'
-import Ref from '../Ref/Ref'
 
 export interface DropdownSearchInputProps extends UIComponentProps<DropdownSearchInputProps> {
   /**
@@ -68,7 +67,7 @@ class DropdownSearchInput extends UIComponent<ReactProps<DropdownSearchInputProp
       content: false,
     }),
     accessibilityInputProps: PropTypes.object,
-    accessibilityWrapperProps: PropTypes.object,
+    accessibilityComboboxProps: PropTypes.object,
     inputRef: PropTypes.func,
     onFocus: PropTypes.func,
     onInputBlur: PropTypes.func,
@@ -98,29 +97,26 @@ class DropdownSearchInput extends UIComponent<ReactProps<DropdownSearchInputProp
   }
 
   public renderComponent({ rest, styles }: RenderResultConfig<DropdownSearchInputProps>) {
-    const { accessibilityWrapperProps, accessibilityInputProps, placeholder } = this.props
-    const { innerRef, ...accessibilityWrapperPropsRest } = accessibilityWrapperProps
+    const { accessibilityComboboxProps, accessibilityInputProps, placeholder } = this.props
     return (
-      <Ref innerRef={innerRef}>
-        <Input
-          inputRef={this.handleInputRef}
-          onFocus={this.handleFocus}
-          onKeyUp={this.handleKeyUp}
-          wrapper={{
-            styles: styles.wrapper,
-            ...accessibilityWrapperPropsRest,
-          }}
-          input={{
-            type: 'text',
-            styles: styles.input,
-            placeholder,
-            onBlur: this.handleInputBlur,
-            onKeyDown: this.handleInputKeyDown,
-            ...accessibilityInputProps,
-          }}
-          {...rest}
-        />
-      </Ref>
+      <Input
+        inputRef={this.handleInputRef}
+        onFocus={this.handleFocus}
+        onKeyUp={this.handleKeyUp}
+        wrapper={{
+          styles: styles.combobox,
+          ...accessibilityComboboxProps,
+        }}
+        input={{
+          type: 'text',
+          styles: styles.input,
+          placeholder,
+          onBlur: this.handleInputBlur,
+          onKeyDown: this.handleInputKeyDown,
+          ...accessibilityInputProps,
+        }}
+        {...rest}
+      />
     )
   }
 }
diff --git a/src/themes/teams/components/Dropdown/dropdownItemStyles.ts b/src/themes/teams/components/Dropdown/dropdownItemStyles.ts
index bf5347c4cd..4e28dbe216 100644
--- a/src/themes/teams/components/Dropdown/dropdownItemStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownItemStyles.ts
@@ -9,8 +9,8 @@ const dropdownItemStyles: ComponentSlotStylesInput<DropdownItemProps, DropdownVa
 
     ...(active && {
       [`&.${ListItem.className}`]: {
-        backgroundColor: v.listItemHighlightedBackgroundColor,
-        color: v.listItemHighlightedTextColor,
+        backgroundColor: v.listItemBackgroundColorActive,
+        color: v.listItemColorActive,
       },
     }),
   }),
diff --git a/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts b/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
index 193a05a58c..e8a04e5c22 100644
--- a/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
@@ -6,17 +6,18 @@ const dropdownSearchInputStyles: ComponentSlotStylesInput<
   DropdownSearchInputProps,
   DropdownVariables
 > = {
-  input: ({ variables: { backgroundColor } }): ICSSInJSStyle => ({
+  input: ({ variables: { backgroundColor, comboboxPaddingInput } }): ICSSInJSStyle => ({
     width: '100%',
     backgroundColor,
+    padding: comboboxPaddingInput,
 
     ':focus': {
       borderBottomColor: 'transparent',
     },
   }),
 
-  wrapper: ({ variables: { editTextFlexBasis } }): ICSSInJSStyle => ({
-    flexBasis: editTextFlexBasis,
+  combobox: ({ variables: { comboboxFlexBasis } }): ICSSInJSStyle => ({
+    flexBasis: comboboxFlexBasis,
     flexGrow: 1,
   }),
 }
diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index 5a2120e940..b16b484fe4 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -3,16 +3,16 @@ import { DropdownProps } from '../../../../components/Dropdown/Dropdown'
 import { DropdownVariables } from './dropdownVariables'
 
 const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables> = {
-  containerDiv: ({
+  root: ({
     props: { focused, toggleButton, fluid },
     variables: {
       backgroundColor,
-      containerDivBorderBottom,
-      containerDivBorderRadius,
-      containerDivBorderColor,
-      containerDivFocusBorderColor,
-      containerDivFocusBorderRadius,
-      containerDivColor,
+      borderBottom,
+      borderRadius,
+      borderColor,
+      borderColorFocus,
+      borderRadiusFocus,
+      color,
       toggleButtonSize,
       width,
     },
@@ -22,33 +22,39 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
     outline: 0,
     border: 0,
     backgroundColor,
-    borderRadius: containerDivBorderRadius,
-    borderBottom: containerDivBorderBottom,
-    borderColor: containerDivBorderColor,
-    color: containerDivColor,
+    borderBottom,
+    borderColor,
+    borderRadius,
+    color,
     width: fluid ? '100%' : width,
     position: 'relative',
     ...(toggleButton && {
       paddingRight: toggleButtonSize,
     }),
     ...(focused && {
-      borderColor: containerDivFocusBorderColor,
-      borderRadius: containerDivFocusBorderRadius,
+      borderColor: borderColorFocus,
+      borderRadius: borderRadiusFocus,
     }),
   }),
 
-  button: (): ICSSInJSStyle => {
+  button: ({ variables: { comboboxPaddingButton } }): ICSSInJSStyle => {
     const transparentColorStyle = {
       backgroundColor: 'transparent',
       borderColor: 'transparent',
     }
     return {
-      boxShadow: '0 0 0 0',
+      boxShadow: 'none',
       margin: '0',
       justifyContent: 'left',
+      padding: comboboxPaddingButton,
       ...transparentColorStyle,
       ':hover': transparentColorStyle,
-      ':focus': transparentColorStyle,
+      ':focus': {
+        ...transparentColorStyle,
+        ':after': {
+          borderColor: 'transparent',
+        },
+      },
       ':active': transparentColorStyle,
     }
   },
diff --git a/src/themes/teams/components/Dropdown/dropdownVariables.ts b/src/themes/teams/components/Dropdown/dropdownVariables.ts
index 32c59c7fd2..95319720d2 100644
--- a/src/themes/teams/components/Dropdown/dropdownVariables.ts
+++ b/src/themes/teams/components/Dropdown/dropdownVariables.ts
@@ -1,39 +1,40 @@
 import { pxToRem } from '../../utils'
 export interface DropdownVariables {
   backgroundColor: string
-  containerDivBorderRadius: string
-  containerDivBorderBottom: string
-  containerDivBorderColor: string
-  containerDivColor: string
-  containerDivFocusBorderColor: string
-  containerDivFocusBorderRadius: string
-  editTextFlexBasis: string
+  borderBottom: string
+  borderColor: string
+  borderColorFocus: string
+  borderRadius: string
+  borderRadiusFocus: string
+  color: string
+  comboboxPaddingButton: string
+  comboboxPaddingInput: string
+  comboboxFlexBasis: string
   listItemBackgroundColor: string
-  listItemHighlightedBackgroundColor: string
-  listItemHighlightedTextColor: string
+  listItemBackgroundColorActive: string
+  listItemColorActive: string
   listMaxHeight: string
   toggleButtonSize: string
   width: string
 }
 
-const [_2px_asRem, _3px_asRem] = [2, 3].map(v => pxToRem(v))
+const [_2px_asRem, _3px_asRem, _6px_asRem, _12px_asRem] = [2, 3, 6, 12].map(v => pxToRem(v))
 
 export default (siteVars): DropdownVariables => ({
   backgroundColor: siteVars.gray10,
-
-  containerDivBorderRadius: _3px_asRem,
-  containerDivBorderBottom: `${_2px_asRem} solid transparent`,
-  containerDivBorderColor: 'transparent',
-  containerDivColor: siteVars.bodyColor,
-  containerDivFocusBorderColor: siteVars.brand,
-  containerDivFocusBorderRadius: `${_3px_asRem} ${_3px_asRem} ${_2px_asRem} ${_2px_asRem}`,
-  editTextFlexBasis: '100px',
-
+  borderRadius: _3px_asRem,
+  borderBottom: `${_2px_asRem} solid transparent`,
+  borderColor: 'transparent',
+  borderColorFocus: siteVars.brand,
+  borderRadiusFocus: `${_3px_asRem} ${_3px_asRem} ${_2px_asRem} ${_2px_asRem}`,
+  color: siteVars.bodyColor,
+  comboboxPaddingButton: `0 ${_12px_asRem}`,
+  comboboxPaddingInput: `${_6px_asRem} ${_12px_asRem}`,
+  comboboxFlexBasis: '50px',
   listItemBackgroundColor: siteVars.white,
-  listItemHighlightedBackgroundColor: siteVars.brand,
-  listItemHighlightedTextColor: siteVars.white,
+  listItemBackgroundColorActive: siteVars.brand,
+  listItemColorActive: siteVars.white,
   listMaxHeight: '20rem',
-
   toggleButtonSize: pxToRem(30),
   width: pxToRem(356),
 })

From ee95d06d9718701533ebed25763e12f4fe25100a Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Tue, 11 Dec 2018 13:17:36 +0200
Subject: [PATCH 32/62] fixed the filtering to work for all variants

---
 src/components/Dropdown/Dropdown.tsx | 42 +++++++++++++++-------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index ef90f67ca4..22acc7cef6 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -231,7 +231,6 @@ export default class Dropdown extends AutoControlledComponent<
             { refKey: 'innerRef' },
             { suppressRefError: true },
           )
-          // const getExpandedRootProps = () => rootAccessibilityProps
           const { innerRef, ...accessibilityRootPropsRest } = accessibilityRootProps
           return (
             <Ref innerRef={innerRef}>
@@ -374,8 +373,8 @@ export default class Dropdown extends AutoControlledComponent<
     getItemProps: (options: GetItemPropsOptions<ShorthandValue>) => any,
     highlightedIndex: number,
   ) {
-    const { items, noResultsMessage } = this.props
-    const filteredItems = this.getItemsFilteredBySearchQuery(items)
+    const { noResultsMessage } = this.props
+    const filteredItems = this.getFilteredItems()
 
     if (filteredItems.length > 0) {
       return filteredItems.map((item, index) => {
@@ -457,25 +456,30 @@ export default class Dropdown extends AutoControlledComponent<
     }
   }
 
-  private getItemsFilteredBySearchQuery = (items: ShorthandValue[]): ShorthandValue[] => {
-    const { itemToString, multiple, search } = this.props
+  private getFilteredItems = (): ShorthandValue[] => {
+    const { items, itemToString, multiple, search } = this.props
     const { searchQuery, value } = this.state
+    let filteredItems = items
 
-    const nonSelectedItems = items.filter(item =>
-      multiple ? (value as ShorthandValue[]).indexOf(item) === -1 : true,
-    )
-
-    const itemsMatchSearchQuery = nonSelectedItems.filter(item =>
-      search
-        ? _.isFunction(search)
-          ? search(itemsMatchSearchQuery, searchQuery)
-          : itemToString(item)
-              .toLowerCase()
-              .indexOf(searchQuery.toLowerCase()) !== -1
-        : true,
-    )
+    if (!multiple && !search) {
+      return items.filter(item => item !== (value as ShorthandValue))
+    }
+    if (multiple) {
+      filteredItems = filteredItems.filter(item => (value as ShorthandValue[]).indexOf(item) === -1)
+    }
+    if (search) {
+      if (_.isFunction(search)) {
+        return search(filteredItems, searchQuery)
+      }
+      return filteredItems.filter(
+        item =>
+          itemToString(item)
+            .toLowerCase()
+            .indexOf(searchQuery.toLowerCase()) !== -1,
+      )
+    }
 
-    return itemsMatchSearchQuery
+    return filteredItems
   }
 
   private setA11yStatus = (statusMessage: string) => {

From bcd061ae18bbf5ce07897ea45b5ad88df333c78a Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Tue, 11 Dec 2018 13:25:56 +0200
Subject: [PATCH 33/62] made the toggleButton tabbable by default

---
 src/components/Dropdown/Dropdown.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 22acc7cef6..7a6ffe243d 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -337,7 +337,7 @@ export default class Dropdown extends AutoControlledComponent<
       <Icon
         name={`chevron ${isOpen ? 'up' : 'down'}`}
         as="button"
-        tabIndex="-1"
+        tabIndex="0"
         styles={styles.toggleButton}
         {...getToggleButtonProps()}
       />

From 7d69d08c575131555aeddf10257a2f0f4a0aeff0 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Tue, 11 Dec 2018 13:31:22 +0200
Subject: [PATCH 34/62] fixed style case active+focus

---
 src/themes/teams/components/Dropdown/dropdownStyles.ts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index b16b484fe4..08b91d8ebf 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -54,6 +54,7 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
         ':after': {
           borderColor: 'transparent',
         },
+        ':active': transparentColorStyle,
       },
       ':active': transparentColorStyle,
     }

From 75ee900cb0bb160a59466529efd762377abf4ad5 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Tue, 11 Dec 2018 15:46:49 +0200
Subject: [PATCH 35/62] fixed wrong import

---
 src/components/Dropdown/Dropdown.tsx | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 7a6ffe243d..564c11c38b 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -28,8 +28,7 @@ import Ref from '../Ref/Ref'
 import { UIComponentProps } from '../../lib/commonPropInterfaces'
 import DropdownItem, { DropdownItemProps } from './DropdownItem'
 import DropdownLabel, { DropdownLabelProps } from './DropdownLabel'
-import DropdownSearchInput from './DropdownSearchInput'
-import { DropdownSearchInputProps } from 'semantic-ui-react'
+import DropdownSearchInput, { DropdownSearchInputProps } from './DropdownSearchInput'
 import Button from '../Button/Button'
 
 // TODO: To be replaced when Downshift will add highlightedItem in their interface.
@@ -352,7 +351,7 @@ export default class Dropdown extends AutoControlledComponent<
     isOpen: boolean,
     highlightedIndex: number,
   ) {
-    const accessibilityMenuProps = getMenuProps({ refKey: 'innerRef' })
+    const accessibilityMenuProps = getMenuProps({ refKey: 'innerRef' }, { suppressRefError: true })
     const { innerRef, ...accessibilityMenuPropsRest } = accessibilityMenuProps
 
     return (

From 868452599f977a20b233d22358f7a30d087af328 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Tue, 11 Dec 2018 17:09:29 +0200
Subject: [PATCH 36/62] fixed ariaLabel for trigger button

---
 src/components/Dropdown/Dropdown.tsx | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 564c11c38b..ee465d6ba8 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -269,11 +269,12 @@ export default class Dropdown extends AutoControlledComponent<
     getToggleButtonProps: (options?: GetToggleButtonPropsOptions) => any,
     styles: ComponentSlotStylesInput,
   ): JSX.Element {
-    const { placeholder, itemToString } = this.props
+    const { placeholder, itemToString, multiple } = this.props
     const { value } = this.state
+    const content = multiple ? placeholder : value ? itemToString(value) : placeholder
     return (
       <Button
-        content={value ? itemToString(value) : placeholder}
+        content={content}
         fluid
         styles={styles.button}
         {...getToggleButtonProps({
@@ -286,6 +287,7 @@ export default class Dropdown extends AutoControlledComponent<
           onClick: e => {
             e.stopPropagation()
           },
+          'aria-label': content, // TODO: add this to behaviour
         })}
       />
     )

From 8a6027177281f0e44ca5becfca02cb86d95dcb65 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Wed, 12 Dec 2018 18:14:05 +0200
Subject: [PATCH 37/62] added list focus and accessibility handling for it

---
 ...opdownExampleSingleSelection.shorthand.tsx |   3 +
 src/components/Dropdown/Dropdown.tsx          | 121 ++++++++++++++----
 2 files changed, 99 insertions(+), 25 deletions(-)

diff --git a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
index 1094c540a4..1145fb1b6c 100644
--- a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
@@ -18,6 +18,9 @@ class DropdownExample extends React.Component {
     return (
       <Dropdown
         getA11yStatusMessage={getA11yStatusMessage}
+        getA11ySelectionMessage={{
+          onAdd: item => `${item} has been selected.`,
+        }}
         placeholder="Select your hero"
         items={inputItems}
       />
diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index ee465d6ba8..eb21b562d4 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -131,6 +131,8 @@ export default class Dropdown extends AutoControlledComponent<
   DropdownState
 > {
   private inputNode: HTMLElement
+  private listNode: HTMLElement
+  private buttonNode: HTMLElement
 
   static displayName = 'Dropdown'
 
@@ -215,6 +217,11 @@ export default class Dropdown extends AutoControlledComponent<
         // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
         selectedItem={search && !multiple ? undefined : null}
         getA11yStatusMessage={getA11yStatusMessage}
+        onStateChange={changes => {
+          if (changes.isOpen && !search) {
+            this.listNode.focus()
+          }
+        }}
       >
         {({
           getInputProps,
@@ -223,6 +230,7 @@ export default class Dropdown extends AutoControlledComponent<
           getRootProps,
           getToggleButtonProps,
           isOpen,
+          toggleMenu,
           highlightedIndex,
           selectItemAtIndex,
         }) => {
@@ -247,15 +255,18 @@ export default class Dropdown extends AutoControlledComponent<
                       selectItemAtIndex,
                       variables,
                     )
-                  : this.renderTriggerButton(getToggleButtonProps, styles)}
+                  : this.renderTriggerButton(styles, getToggleButtonProps)}
                 {toggleButton && this.renderToggleButton(getToggleButtonProps, styles, isOpen)}
                 {this.renderItemsList(
                   styles,
                   variables,
-                  getMenuProps,
-                  getItemProps,
                   isOpen,
                   highlightedIndex,
+                  toggleMenu,
+                  selectItemAtIndex,
+                  getMenuProps,
+                  getItemProps,
+                  getInputProps,
                 )}
               </ElementType>
             </Ref>
@@ -266,30 +277,33 @@ export default class Dropdown extends AutoControlledComponent<
   }
 
   private renderTriggerButton(
-    getToggleButtonProps: (options?: GetToggleButtonPropsOptions) => any,
     styles: ComponentSlotStylesInput,
+    getToggleButtonProps: (options?: GetToggleButtonPropsOptions) => any,
   ): JSX.Element {
     const { placeholder, itemToString, multiple } = this.props
     const { value } = this.state
     const content = multiple ? placeholder : value ? itemToString(value) : placeholder
     return (
-      <Button
-        content={content}
-        fluid
-        styles={styles.button}
-        {...getToggleButtonProps({
-          onFocus: () => {
-            this.setState({ focused: true })
-          },
-          onBlur: () => {
-            this.setState({ focused: false })
-          },
-          onClick: e => {
-            e.stopPropagation()
-          },
-          'aria-label': content, // TODO: add this to behaviour
-        })}
-      />
+      <Ref
+        innerRef={buttonNode => {
+          this.buttonNode = buttonNode
+        }}
+      >
+        <Button
+          content={content}
+          fluid
+          styles={styles.button}
+          {...getToggleButtonProps({
+            onFocus: () => {
+              this.setState({ focused: true })
+            },
+            onBlur: () => {
+              this.setState({ focused: false })
+            },
+            'aria-label': content, // TODO: add this to behaviour
+          })}
+        />
+      </Ref>
     )
   }
 
@@ -348,19 +362,44 @@ export default class Dropdown extends AutoControlledComponent<
   private renderItemsList(
     styles: ComponentSlotStylesInput,
     variables: ComponentVariablesInput,
-    getMenuProps: (options?: GetMenuPropsOptions, otherOptions?: GetPropsCommonOptions) => any,
-    getItemProps: (options: GetItemPropsOptions<ShorthandValue>) => any,
     isOpen: boolean,
     highlightedIndex: number,
+    toggleMenu: () => void,
+    selectItemAtIndex: (index: number) => void,
+    getMenuProps: (options?: GetMenuPropsOptions, otherOptions?: GetPropsCommonOptions) => any,
+    getItemProps: (options: GetItemPropsOptions<ShorthandValue>) => any,
+    getInputProps: (options?: GetInputPropsOptions) => any,
   ) {
-    const accessibilityMenuProps = getMenuProps({ refKey: 'innerRef' }, { suppressRefError: true })
+    const accessibilityMenuProps = {
+      ...getMenuProps({ refKey: 'innerRef' }, { suppressRefError: true }),
+    }
+    if (!this.props.search) {
+      const accessibilityInputProps = getInputProps()
+      accessibilityMenuProps['aria-activedescendant'] =
+        accessibilityInputProps['aria-activedescendant']
+      accessibilityMenuProps['onKeyDown'] = e => {
+        this.handleListKeyDown(
+          e,
+          highlightedIndex,
+          accessibilityInputProps['onKeyDown'],
+          toggleMenu,
+          selectItemAtIndex,
+        )
+      }
+    }
     const { innerRef, ...accessibilityMenuPropsRest } = accessibilityMenuProps
 
     return (
-      <Ref innerRef={innerRef}>
+      <Ref
+        innerRef={(listNode: HTMLElement) => {
+          this.listNode = listNode
+          innerRef(listNode)
+        }}
+      >
         <List
           {...accessibilityMenuPropsRest}
           styles={styles.list}
+          tabIndex={-1}
           aria-hidden={!isOpen}
           items={isOpen ? this.renderItems(styles, variables, getItemProps, highlightedIndex) : []}
         />
@@ -452,6 +491,12 @@ export default class Dropdown extends AutoControlledComponent<
           { ...this.props, searchQuery: changes.inputValue },
         )
         return changes
+      case Downshift.stateChangeTypes.blurButton:
+        // Focus the list, by button click/enter/up/down/space. Downshift, by default, closes the list
+        // on trigger blur, but in this case it's custom behaviour, where we want to keep it open.
+        if (state.isOpen) {
+          return {}
+        }
       default:
         return changes
     }
@@ -615,6 +660,32 @@ export default class Dropdown extends AutoControlledComponent<
     !isOpen && this.inputNode.focus()
   }
 
+  private handleListKeyDown = (
+    e: React.SyntheticEvent,
+    highlightedIndex: number,
+    accessibilityInputPropsKeyDown: (e) => any,
+    toggleMenu: () => void,
+    selectItemAtIndex: (index: number) => void,
+  ) => {
+    switch (keyboardKey.getCode(e)) {
+      case keyboardKey.Tab:
+        if (_.isNil(highlightedIndex)) {
+          toggleMenu()
+        } else {
+          selectItemAtIndex(highlightedIndex)
+        }
+        return
+      case keyboardKey.Enter:
+      case keyboardKey.Escape:
+        accessibilityInputPropsKeyDown(e)
+        this.buttonNode.focus()
+        return
+      default:
+        accessibilityInputPropsKeyDown(e)
+        return
+    }
+  }
+
   private handleSelectedChange = (item: ShorthandValue) => {
     const { multiple, getA11ySelectionMessage } = this.props
     const newValue = multiple ? [...(this.state.value as ShorthandValue[]), item] : item

From 5aa379e4c193e65cb1901992302220a1fc967e88 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 13 Dec 2018 10:14:21 +0200
Subject: [PATCH 38/62] fixed toggle button bug that appeared after trigger fix

---
 src/components/Dropdown/Dropdown.tsx | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index eb21b562d4..a0e850ee64 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -492,10 +492,10 @@ export default class Dropdown extends AutoControlledComponent<
         )
         return changes
       case Downshift.stateChangeTypes.blurButton:
-        // Focus the list, by button click/enter/up/down/space. Downshift, by default, closes the list
-        // on trigger blur, but in this case it's custom behaviour, where we want to keep it open.
-        if (state.isOpen) {
-          return {}
+        // Downshift closes the list by default on trigger blur. It does not support the case when dropdown is
+        // single selection and focuses list on trigger click/up/down/space/enter. Treating that here.
+        if (state.isOpen && document.activeElement === this.listNode) {
+          return {} // won't change state in this case.
         }
       default:
         return changes
@@ -599,7 +599,7 @@ export default class Dropdown extends AutoControlledComponent<
       e: React.SyntheticEvent,
       searchInputProps: DropdownSearchInputProps,
     ) => {
-      if (keyboardKey.getCode(e) === keyboardKey.Tab && highlightedIndex !== undefined) {
+      if (keyboardKey.getCode(e) === keyboardKey.Tab && _.isNil(highlightedIndex)) {
         selectItemAtIndex(highlightedIndex)
       }
 

From eeaf144ad4d49a9452b4a0760607e57a4419c16e Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 13 Dec 2018 11:23:21 +0200
Subject: [PATCH 39/62] reverted change for filteredItems

---
 src/components/Dropdown/Dropdown.tsx | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index a0e850ee64..3b014c41bf 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -414,7 +414,7 @@ export default class Dropdown extends AutoControlledComponent<
     highlightedIndex: number,
   ) {
     const { noResultsMessage } = this.props
-    const filteredItems = this.getFilteredItems()
+    const filteredItems = this.getItemsFilteredBySearchQuery()
 
     if (filteredItems.length > 0) {
       return filteredItems.map((item, index) => {
@@ -502,14 +502,11 @@ export default class Dropdown extends AutoControlledComponent<
     }
   }
 
-  private getFilteredItems = (): ShorthandValue[] => {
+  private getItemsFilteredBySearchQuery = (): ShorthandValue[] => {
     const { items, itemToString, multiple, search } = this.props
     const { searchQuery, value } = this.state
     let filteredItems = items
 
-    if (!multiple && !search) {
-      return items.filter(item => item !== (value as ShorthandValue))
-    }
     if (multiple) {
       filteredItems = filteredItems.filter(item => (value as ShorthandValue[]).indexOf(item) === -1)
     }

From c2861334644d54900b9ffe68972a7c0edab068ee Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 13 Dec 2018 11:52:53 +0200
Subject: [PATCH 40/62] refactored the renderComponent to pass conformance

---
 src/components/Dropdown/Dropdown.tsx          | 129 +++++++++---------
 .../components/Dropdown/dropdownStyles.ts     |   4 +-
 2 files changed, 68 insertions(+), 65 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 3b014c41bf..7218a198b1 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -209,70 +209,71 @@ export default class Dropdown extends AutoControlledComponent<
     const { searchQuery } = this.state
 
     return (
-      <Downshift
-        onChange={this.handleSelectedChange}
-        inputValue={search ? searchQuery : undefined}
-        stateReducer={this.handleDownshiftStateChanges}
-        itemToString={itemToString}
-        // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
-        selectedItem={search && !multiple ? undefined : null}
-        getA11yStatusMessage={getA11yStatusMessage}
-        onStateChange={changes => {
-          if (changes.isOpen && !search) {
-            this.listNode.focus()
-          }
-        }}
-      >
-        {({
-          getInputProps,
-          getItemProps,
-          getMenuProps,
-          getRootProps,
-          getToggleButtonProps,
-          isOpen,
-          toggleMenu,
-          highlightedIndex,
-          selectItemAtIndex,
-        }) => {
-          const accessibilityRootProps = getRootProps(
-            { refKey: 'innerRef' },
-            { suppressRefError: true },
-          )
-          const { innerRef, ...accessibilityRootPropsRest } = accessibilityRootProps
-          return (
-            <Ref innerRef={innerRef}>
-              <ElementType
-                className={classes.root}
-                onClick={multiple ? this.handleContainerClick.bind(this, isOpen) : undefined}
-                {...rest}
-              >
-                {multiple && this.renderSelectedItems(styles)}
-                {search
-                  ? this.renderSearchInput(
-                      accessibilityRootPropsRest,
-                      getInputProps,
-                      highlightedIndex,
-                      selectItemAtIndex,
-                      variables,
-                    )
-                  : this.renderTriggerButton(styles, getToggleButtonProps)}
-                {toggleButton && this.renderToggleButton(getToggleButtonProps, styles, isOpen)}
-                {this.renderItemsList(
-                  styles,
-                  variables,
-                  isOpen,
-                  highlightedIndex,
-                  toggleMenu,
-                  selectItemAtIndex,
-                  getMenuProps,
-                  getItemProps,
-                  getInputProps,
-                )}
-              </ElementType>
-            </Ref>
-          )
-        }}
-      </Downshift>
+      <ElementType className={classes.root} {...rest}>
+        <Downshift
+          onChange={this.handleSelectedChange}
+          inputValue={search ? searchQuery : undefined}
+          stateReducer={this.handleDownshiftStateChanges}
+          itemToString={itemToString}
+          // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
+          selectedItem={search && !multiple ? undefined : null}
+          getA11yStatusMessage={getA11yStatusMessage}
+          onStateChange={changes => {
+            if (changes.isOpen && !search) {
+              this.listNode.focus()
+            }
+          }}
+        >
+          {({
+            getInputProps,
+            getItemProps,
+            getMenuProps,
+            getRootProps,
+            getToggleButtonProps,
+            isOpen,
+            toggleMenu,
+            highlightedIndex,
+            selectItemAtIndex,
+          }) => {
+            const accessibilityRootProps = getRootProps(
+              { refKey: 'innerRef' },
+              { suppressRefError: true },
+            )
+            const { innerRef, ...accessibilityRootPropsRest } = accessibilityRootProps
+            return (
+              <Ref innerRef={innerRef}>
+                <div
+                  className={classes.container}
+                  onClick={multiple ? this.handleContainerClick.bind(this, isOpen) : undefined}
+                >
+                  {multiple && this.renderSelectedItems(styles)}
+                  {search
+                    ? this.renderSearchInput(
+                        accessibilityRootPropsRest,
+                        getInputProps,
+                        highlightedIndex,
+                        selectItemAtIndex,
+                        variables,
+                      )
+                    : this.renderTriggerButton(styles, getToggleButtonProps)}
+                  {toggleButton && this.renderToggleButton(getToggleButtonProps, styles, isOpen)}
+                  {this.renderItemsList(
+                    styles,
+                    variables,
+                    isOpen,
+                    highlightedIndex,
+                    toggleMenu,
+                    selectItemAtIndex,
+                    getMenuProps,
+                    getItemProps,
+                    getInputProps,
+                  )}
+                </div>
+              </Ref>
+            )
+          }}
+        </Downshift>
+      </ElementType>
     )
   }
 
diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index 08b91d8ebf..81639105b9 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -3,7 +3,9 @@ import { DropdownProps } from '../../../../components/Dropdown/Dropdown'
 import { DropdownVariables } from './dropdownVariables'
 
 const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables> = {
-  root: ({
+  root: (): ICSSInJSStyle => ({}),
+
+  container: ({
     props: { focused, toggleButton, fluid },
     variables: {
       backgroundColor,

From 1ec202817b9beefcbebd862deb8410c4d78fd4d5 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 13 Dec 2018 11:55:50 +0200
Subject: [PATCH 41/62] fixed button focus at selection

---
 src/components/Dropdown/Dropdown.tsx | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 7218a198b1..ca43a881bf 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -673,7 +673,6 @@ export default class Dropdown extends AutoControlledComponent<
           selectItemAtIndex(highlightedIndex)
         }
         return
-      case keyboardKey.Enter:
       case keyboardKey.Escape:
         accessibilityInputPropsKeyDown(e)
         this.buttonNode.focus()
@@ -685,7 +684,7 @@ export default class Dropdown extends AutoControlledComponent<
   }
 
   private handleSelectedChange = (item: ShorthandValue) => {
-    const { multiple, getA11ySelectionMessage } = this.props
+    const { multiple, getA11ySelectionMessage, search } = this.props
     const newValue = multiple ? [...(this.state.value as ShorthandValue[]), item] : item
 
     this.trySetState({
@@ -695,6 +694,9 @@ export default class Dropdown extends AutoControlledComponent<
     if (getA11ySelectionMessage && getA11ySelectionMessage.onAdd) {
       this.setA11yStatus(getA11ySelectionMessage.onAdd(item))
     }
+    if (!search) {
+      this.buttonNode.focus()
+    }
 
     // we don't have event for it, but want to keep the event handling interface, event is empty.
     _.invoke(this.props, 'onSelectedChange', {}, { ...this.props, value: newValue })

From c19c12f7fda1134a507e7f34175a18222a0901ed Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 13 Dec 2018 18:39:39 +0200
Subject: [PATCH 42/62] merged ref code review improvement

---
 src/components/Dropdown/Dropdown.tsx | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index ca43a881bf..2a01dc3538 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -132,7 +132,7 @@ export default class Dropdown extends AutoControlledComponent<
 > {
   private inputNode: HTMLElement
   private listNode: HTMLElement
-  private buttonNode: HTMLElement
+  private buttonRef = React.createRef<HTMLElement>()
 
   static displayName = 'Dropdown'
 
@@ -285,11 +285,7 @@ export default class Dropdown extends AutoControlledComponent<
     const { value } = this.state
     const content = multiple ? placeholder : value ? itemToString(value) : placeholder
     return (
-      <Ref
-        innerRef={buttonNode => {
-          this.buttonNode = buttonNode
-        }}
-      >
+      <Ref innerRef={this.buttonRef}>
         <Button
           content={content}
           fluid
@@ -675,7 +671,7 @@ export default class Dropdown extends AutoControlledComponent<
         return
       case keyboardKey.Escape:
         accessibilityInputPropsKeyDown(e)
-        this.buttonNode.focus()
+        this.buttonRef.current.focus()
         return
       default:
         accessibilityInputPropsKeyDown(e)
@@ -695,7 +691,7 @@ export default class Dropdown extends AutoControlledComponent<
       this.setA11yStatus(getA11ySelectionMessage.onAdd(item))
     }
     if (!search) {
-      this.buttonNode.focus()
+      this.buttonRef.current.focus()
     }
 
     // we don't have event for it, but want to keep the event handling interface, event is empty.

From 862c4bd0783fda8920ab4f6002d694824bf41f33 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 13 Dec 2018 19:17:00 +0200
Subject: [PATCH 43/62] removed unneeded code

---
 src/components/Dropdown/Dropdown.tsx | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 2a01dc3538..bf88d1e7b5 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -415,13 +415,7 @@ export default class Dropdown extends AutoControlledComponent<
 
     if (filteredItems.length > 0) {
       return filteredItems.map((item, index) => {
-        let itemAsListItem = item
-        if (typeof item === 'object') {
-          itemAsListItem = _.pickBy(item, (value, key) =>
-            _.includes(['key', ...DropdownItem.handledProps], key),
-          )
-        }
-        return DropdownItem.create(itemAsListItem, {
+        return DropdownItem.create(item, {
           defaultProps: {
             active: highlightedIndex === index,
             variables,

From 945bb954dd5c86906942a739e607eac7a0fa0c8d Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Fri, 14 Dec 2018 11:37:30 +0200
Subject: [PATCH 44/62] removed ternary condition

---
 src/components/Dropdown/Dropdown.tsx | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index bf88d1e7b5..0ce06179ff 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -283,7 +283,14 @@ export default class Dropdown extends AutoControlledComponent<
   ): JSX.Element {
     const { placeholder, itemToString, multiple } = this.props
     const { value } = this.state
-    const content = multiple ? placeholder : value ? itemToString(value) : placeholder
+    let content
+
+    if (multiple) {
+      content = placeholder
+    } else {
+      content = value ? itemToString(value) : placeholder
+    }
+
     return (
       <Ref innerRef={this.buttonRef}>
         <Button

From 0675513f77aa1a322846907cf89446a6f146bffd Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Wed, 2 Jan 2019 17:11:49 +0200
Subject: [PATCH 45/62] replaced some heights to make toggle button appear
 centered

---
 src/themes/teams/components/Dropdown/dropdownStyles.ts    | 2 ++
 src/themes/teams/components/Dropdown/dropdownVariables.ts | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index 81639105b9..446b22fb4a 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -1,6 +1,7 @@
 import { ComponentSlotStylesInput, ICSSInJSStyle } from '../../../types'
 import { DropdownProps } from '../../../../components/Dropdown/Dropdown'
 import { DropdownVariables } from './dropdownVariables'
+import { pxToRem } from '../../utils'
 
 const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables> = {
   root: (): ICSSInJSStyle => ({}),
@@ -50,6 +51,7 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
       justifyContent: 'left',
       padding: comboboxPaddingButton,
       ...transparentColorStyle,
+      height: pxToRem(30),
       ':hover': transparentColorStyle,
       ':focus': {
         ...transparentColorStyle,
diff --git a/src/themes/teams/components/Dropdown/dropdownVariables.ts b/src/themes/teams/components/Dropdown/dropdownVariables.ts
index 95319720d2..d92e33e739 100644
--- a/src/themes/teams/components/Dropdown/dropdownVariables.ts
+++ b/src/themes/teams/components/Dropdown/dropdownVariables.ts
@@ -35,6 +35,6 @@ export default (siteVars): DropdownVariables => ({
   listItemBackgroundColorActive: siteVars.brand,
   listItemColorActive: siteVars.white,
   listMaxHeight: '20rem',
-  toggleButtonSize: pxToRem(30),
+  toggleButtonSize: pxToRem(32),
   width: pxToRem(356),
 })

From c571d9217933189d6a4ab7adfe35fea0abede047 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Wed, 2 Jan 2019 19:05:39 +0200
Subject: [PATCH 46/62] improvements on styles from code review

---
 src/components/Dropdown/Dropdown.tsx               | 14 ++++++++------
 src/components/Dropdown/DropdownSearchInput.tsx    |  3 +++
 .../Dropdown/dropdownSearchInputStyles.ts          |  8 +++++++-
 .../teams/components/Dropdown/dropdownStyles.ts    | 11 +++++------
 4 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 0ce06179ff..f3a8f9d6bc 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -304,7 +304,6 @@ export default class Dropdown extends AutoControlledComponent<
             onBlur: () => {
               this.setState({ focused: false })
             },
-            'aria-label': content, // TODO: add this to behaviour
           })}
         />
       </Ref>
@@ -322,7 +321,7 @@ export default class Dropdown extends AutoControlledComponent<
     ) => void,
     variables,
   ): JSX.Element {
-    const { searchInput, multiple, placeholder } = this.props
+    const { searchInput, multiple, placeholder, toggleButton } = this.props
     const { searchQuery, value } = this.state
 
     const noPlaceholder =
@@ -331,6 +330,7 @@ export default class Dropdown extends AutoControlledComponent<
     return DropdownSearchInput.create(searchInput || {}, {
       defaultProps: {
         placeholder: noPlaceholder ? '' : placeholder,
+        hasToggleButton: !!toggleButton,
         variables,
         inputRef: (inputNode: HTMLElement) => {
           this.inputNode = inputNode
@@ -352,13 +352,15 @@ export default class Dropdown extends AutoControlledComponent<
     styles: ComponentSlotStylesInput,
     isOpen: boolean,
   ) {
+    const { onClick, onBlur, onKeyDown, onKeyUp } = getToggleButtonProps()
     return (
       <Icon
         name={`chevron ${isOpen ? 'up' : 'down'}`}
-        as="button"
-        tabIndex="0"
         styles={styles.toggleButton}
-        {...getToggleButtonProps()}
+        onClick={onClick}
+        onBlur={onBlur}
+        onKeyDown={onKeyDown}
+        onKeyUp={onKeyUp}
       />
     )
   }
@@ -594,7 +596,7 @@ export default class Dropdown extends AutoControlledComponent<
       e: React.SyntheticEvent,
       searchInputProps: DropdownSearchInputProps,
     ) => {
-      if (keyboardKey.getCode(e) === keyboardKey.Tab && _.isNil(highlightedIndex)) {
+      if (keyboardKey.getCode(e) === keyboardKey.Tab && !_.isNil(highlightedIndex)) {
         selectItemAtIndex(highlightedIndex)
       }
 
diff --git a/src/components/Dropdown/DropdownSearchInput.tsx b/src/components/Dropdown/DropdownSearchInput.tsx
index 6a4a4db94c..a6ed33276a 100644
--- a/src/components/Dropdown/DropdownSearchInput.tsx
+++ b/src/components/Dropdown/DropdownSearchInput.tsx
@@ -8,6 +8,8 @@ import { UIComponentProps } from '../../lib/commonPropInterfaces'
 import Input from '../Input/Input'
 
 export interface DropdownSearchInputProps extends UIComponentProps<DropdownSearchInputProps> {
+  /** Informs the search input about an existing toggle button. */
+  hasToggleButton?: boolean
   /**
    * Ref callback with an input DOM node.
    *
@@ -68,6 +70,7 @@ class DropdownSearchInput extends UIComponent<ReactProps<DropdownSearchInputProp
     }),
     accessibilityInputProps: PropTypes.object,
     accessibilityComboboxProps: PropTypes.object,
+    hasToggleButton: PropTypes.bool,
     inputRef: PropTypes.func,
     onFocus: PropTypes.func,
     onInputBlur: PropTypes.func,
diff --git a/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts b/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
index e8a04e5c22..bd496b3eb2 100644
--- a/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
@@ -16,9 +16,15 @@ const dropdownSearchInputStyles: ComponentSlotStylesInput<
     },
   }),
 
-  combobox: ({ variables: { comboboxFlexBasis } }): ICSSInJSStyle => ({
+  combobox: ({
+    variables: { comboboxFlexBasis, toggleButtonSize },
+    props: { hasToggleButton },
+  }): ICSSInJSStyle => ({
     flexBasis: comboboxFlexBasis,
     flexGrow: 1,
+    ...(hasToggleButton && {
+      paddingRight: toggleButtonSize,
+    }),
   }),
 }
 
diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index 446b22fb4a..fbf29496cf 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -7,7 +7,7 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
   root: (): ICSSInJSStyle => ({}),
 
   container: ({
-    props: { focused, toggleButton, fluid },
+    props: { focused, fluid },
     variables: {
       backgroundColor,
       borderBottom,
@@ -16,7 +16,6 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
       borderColorFocus,
       borderRadiusFocus,
       color,
-      toggleButtonSize,
       width,
     },
   }): ICSSInJSStyle => ({
@@ -31,9 +30,6 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
     color,
     width: fluid ? '100%' : width,
     position: 'relative',
-    ...(toggleButton && {
-      paddingRight: toggleButtonSize,
-    }),
     ...(focused && {
       borderColor: borderColorFocus,
       borderRadius: borderRadiusFocus,
@@ -85,9 +81,12 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
     position: 'absolute',
     height: toggleButtonSize,
     width: toggleButtonSize,
-    border: 0,
+    cursor: 'pointer',
     backgroundColor: 'transparent',
     margin: 0,
+    display: 'flex',
+    justifyContent: 'center',
+    alignItems: 'center',
     ...(fluid ? { right: 0 } : { left: `calc(${width} - ${toggleButtonSize})` }),
   }),
 }

From 277175eda5a82025e18603953ed12f08beb929cc Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 10:39:45 +0200
Subject: [PATCH 47/62] replaced Icon with unicode char for theme consistency

---
 src/components/Dropdown/Dropdown.tsx | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index f3a8f9d6bc..9a4753cb50 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -3,7 +3,11 @@ import * as PropTypes from 'prop-types'
 import * as _ from 'lodash'
 
 import { Extendable, ShorthandValue, ComponentEventHandler } from '../../../types/utils'
-import { ComponentSlotStylesInput, ComponentVariablesInput } from '../../themes/types'
+import {
+  ComponentSlotStylesInput,
+  ComponentVariablesInput,
+  ComponentSlotClasses,
+} from '../../themes/types'
 import Downshift, {
   DownshiftState,
   StateChangeOptions,
@@ -23,7 +27,6 @@ import {
 import keyboardKey from 'keyboard-key'
 import List from '../List/List'
 import Text from '../Text/Text'
-import Icon from '../Icon/Icon'
 import Ref from '../Ref/Ref'
 import { UIComponentProps } from '../../lib/commonPropInterfaces'
 import DropdownItem, { DropdownItemProps } from './DropdownItem'
@@ -256,7 +259,7 @@ export default class Dropdown extends AutoControlledComponent<
                         variables,
                       )
                     : this.renderTriggerButton(styles, getToggleButtonProps)}
-                  {toggleButton && this.renderToggleButton(getToggleButtonProps, styles, isOpen)}
+                  {toggleButton && this.renderToggleButton(getToggleButtonProps, classes, isOpen)}
                   {this.renderItemsList(
                     styles,
                     variables,
@@ -349,19 +352,14 @@ export default class Dropdown extends AutoControlledComponent<
 
   private renderToggleButton(
     getToggleButtonProps: (options?: GetToggleButtonPropsOptions) => any,
-    styles: ComponentSlotStylesInput,
+    classes: ComponentSlotClasses,
     isOpen: boolean,
   ) {
-    const { onClick, onBlur, onKeyDown, onKeyUp } = getToggleButtonProps()
+    const { onClick } = getToggleButtonProps()
     return (
-      <Icon
-        name={`chevron ${isOpen ? 'up' : 'down'}`}
-        styles={styles.toggleButton}
-        onClick={onClick}
-        onBlur={onBlur}
-        onKeyDown={onKeyDown}
-        onKeyUp={onKeyUp}
-      />
+      <span className={classes.toggleButton} onClick={onClick}>
+        {isOpen ? String.fromCharCode(9650) : String.fromCharCode(9660)}
+      </span>
     )
   }
 

From 83fc34dfcfb45d150c2b43c6d277841d0a4c4f23 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 11:58:50 +0200
Subject: [PATCH 48/62] some more review comments handled

---
 src/components/Dropdown/Dropdown.tsx | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 9a4753cb50..d8a8395745 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -218,7 +218,8 @@ export default class Dropdown extends AutoControlledComponent<
           inputValue={search ? searchQuery : undefined}
           stateReducer={this.handleDownshiftStateChanges}
           itemToString={itemToString}
-          // Downshift does not support multiple selection. We will handle everything and pass it selected as null in this case.
+          // If it's single search, don't pass anything. Pass a null otherwise, as Downshift does
+          // not handle selection by default for single/multiple selection and multiple search.
           selectedItem={search && !multiple ? undefined : null}
           getA11yStatusMessage={getA11yStatusMessage}
           onStateChange={changes => {
@@ -286,13 +287,7 @@ export default class Dropdown extends AutoControlledComponent<
   ): JSX.Element {
     const { placeholder, itemToString, multiple } = this.props
     const { value } = this.state
-    let content
-
-    if (multiple) {
-      content = placeholder
-    } else {
-      content = value ? itemToString(value) : placeholder
-    }
+    const content = value && !multiple ? itemToString(value) : placeholder
 
     return (
       <Ref innerRef={this.buttonRef}>

From cf48f4b89dbb4a8df52c2ffe120a89617d055a88 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 12:40:08 +0200
Subject: [PATCH 49/62] some more code improvements in Dropdown

---
 src/components/Dropdown/Dropdown.tsx | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index d8a8395745..83afe6b3c9 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -29,7 +29,7 @@ import List from '../List/List'
 import Text from '../Text/Text'
 import Ref from '../Ref/Ref'
 import { UIComponentProps } from '../../lib/commonPropInterfaces'
-import DropdownItem, { DropdownItemProps } from './DropdownItem'
+import DropdownItem from './DropdownItem'
 import DropdownLabel, { DropdownLabelProps } from './DropdownLabel'
 import DropdownSearchInput, { DropdownSearchInputProps } from './DropdownSearchInput'
 import Button from '../Button/Button'
@@ -239,11 +239,10 @@ export default class Dropdown extends AutoControlledComponent<
             highlightedIndex,
             selectItemAtIndex,
           }) => {
-            const accessibilityRootProps = getRootProps(
+            const { innerRef, ...accessibilityRootPropsRest } = getRootProps(
               { refKey: 'innerRef' },
               { suppressRefError: true },
             )
-            const { innerRef, ...accessibilityRootPropsRest } = accessibilityRootProps
             return (
               <Ref innerRef={innerRef}>
                 <div
@@ -369,9 +368,8 @@ export default class Dropdown extends AutoControlledComponent<
     getItemProps: (options: GetItemPropsOptions<ShorthandValue>) => any,
     getInputProps: (options?: GetInputPropsOptions) => any,
   ) {
-    const accessibilityMenuProps = {
-      ...getMenuProps({ refKey: 'innerRef' }, { suppressRefError: true }),
-    }
+    const accessibilityMenuProps = getMenuProps({ refKey: 'innerRef' }, { suppressRefError: true })
+    // If it's just a selection, some attributes and listeners from Downshift input need to go on the menu list.
     if (!this.props.search) {
       const accessibilityInputProps = getInputProps()
       accessibilityMenuProps['aria-activedescendant'] =
@@ -387,7 +385,6 @@ export default class Dropdown extends AutoControlledComponent<
       }
     }
     const { innerRef, ...accessibilityMenuPropsRest } = accessibilityMenuProps
-
     return (
       <Ref
         innerRef={(listNode: HTMLElement) => {
@@ -426,8 +423,7 @@ export default class Dropdown extends AutoControlledComponent<
                 key: (item as any).header,
               }),
           },
-          overrideProps: (predefinedProps: DropdownItemProps) =>
-            this.handleItemOverrides(item, index, getItemProps),
+          overrideProps: () => this.handleItemOverrides(item, index, getItemProps),
         })
       })
     }

From b9d5412cc3430cb3ebd0b2777aab1927ce0b78e7 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 12:40:28 +0200
Subject: [PATCH 50/62] replaced right margin with padding for combobox

---
 .../teams/components/Dropdown/dropdownSearchInputStyles.ts      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts b/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
index bd496b3eb2..16c52581ff 100644
--- a/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts
@@ -23,7 +23,7 @@ const dropdownSearchInputStyles: ComponentSlotStylesInput<
     flexBasis: comboboxFlexBasis,
     flexGrow: 1,
     ...(hasToggleButton && {
-      paddingRight: toggleButtonSize,
+      marginRight: toggleButtonSize,
     }),
   }),
 }

From d2ae9e1fd821d75ad8aebdd9bfbe29d6da650a1d Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 12:59:42 +0200
Subject: [PATCH 51/62] used functional components in the examples

---
 ...ropdownExampleMultipleSearch.shorthand.tsx | 26 +++++++----------
 ...opdownExampleSingleSelection.shorthand.tsx | 24 +++++++--------
 ...wnExampleMultipleSearchFluid.shorthand.tsx | 29 ++++++++-----------
 ...ultipleSearchImageAndContent.shorthand.tsx | 26 +++++++----------
 ...leMultipleSearchToggleButton.shorthand.tsx | 28 ++++++++----------
 5 files changed, 56 insertions(+), 77 deletions(-)

diff --git a/docs/src/examples/components/Dropdown/Types/DropdownExampleMultipleSearch.shorthand.tsx b/docs/src/examples/components/Dropdown/Types/DropdownExampleMultipleSearch.shorthand.tsx
index 4dc983cd0c..6aba57a1d9 100644
--- a/docs/src/examples/components/Dropdown/Types/DropdownExampleMultipleSearch.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Types/DropdownExampleMultipleSearch.shorthand.tsx
@@ -13,21 +13,17 @@ const inputItems = [
   'Selina Kyle',
 ]
 
-class DropdownExample extends React.Component {
-  render() {
-    return (
-      <Dropdown
-        multiple
-        search
-        getA11ySelectionMessage={getA11ySelectionMessage}
-        getA11yStatusMessage={getA11yStatusMessage}
-        noResultsMessage="We couldn't find any matches."
-        placeholder="Start typing a name"
-        items={inputItems}
-      />
-    )
-  }
-}
+const DropdownExample = () => (
+  <Dropdown
+    multiple
+    search
+    getA11ySelectionMessage={getA11ySelectionMessage}
+    getA11yStatusMessage={getA11yStatusMessage}
+    noResultsMessage="We couldn't find any matches."
+    placeholder="Start typing a name"
+    items={inputItems}
+  />
+)
 
 const getA11ySelectionMessage = {
   onAdd: item => `${item} has been selected.`,
diff --git a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
index 1145fb1b6c..c4f046d982 100644
--- a/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Types/DropdownExampleSingleSelection.shorthand.tsx
@@ -13,20 +13,16 @@ const inputItems = [
   'Selina Kyle',
 ]
 
-class DropdownExample extends React.Component {
-  render() {
-    return (
-      <Dropdown
-        getA11yStatusMessage={getA11yStatusMessage}
-        getA11ySelectionMessage={{
-          onAdd: item => `${item} has been selected.`,
-        }}
-        placeholder="Select your hero"
-        items={inputItems}
-      />
-    )
-  }
-}
+const DropdownExample = () => (
+  <Dropdown
+    getA11yStatusMessage={getA11yStatusMessage}
+    getA11ySelectionMessage={{
+      onAdd: item => `${item} has been selected.`,
+    }}
+    placeholder="Select your hero"
+    items={inputItems}
+  />
+)
 
 const getA11yStatusMessage = ({
   isOpen,
diff --git a/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchFluid.shorthand.tsx b/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchFluid.shorthand.tsx
index 7dd60f245a..5d1de96419 100644
--- a/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchFluid.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchFluid.shorthand.tsx
@@ -12,23 +12,18 @@ const inputItems = [
   'Peter Parker',
   'Selina Kyle',
 ]
-
-class DropdownExample extends React.Component {
-  render() {
-    return (
-      <Dropdown
-        multiple
-        getA11ySelectionMessage={getA11ySelectionMessage}
-        getA11yStatusMessage={getA11yStatusMessage}
-        noResultsMessage="We couldn't find any matches."
-        search
-        fluid
-        placeholder="Start typing a name"
-        items={inputItems}
-      />
-    )
-  }
-}
+const DropdownExample = () => (
+  <Dropdown
+    multiple
+    getA11ySelectionMessage={getA11ySelectionMessage}
+    getA11yStatusMessage={getA11yStatusMessage}
+    noResultsMessage="We couldn't find any matches."
+    search
+    fluid
+    placeholder="Start typing a name"
+    items={inputItems}
+  />
+)
 
 const getA11ySelectionMessage = {
   onAdd: item => `${item} has been selected.`,
diff --git a/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchImageAndContent.shorthand.tsx b/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchImageAndContent.shorthand.tsx
index ed52d80f56..248055b67a 100644
--- a/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchImageAndContent.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchImageAndContent.shorthand.tsx
@@ -49,21 +49,17 @@ const inputItems = [
   },
 ]
 
-class DropdownExample extends React.Component {
-  render() {
-    return (
-      <Dropdown
-        multiple
-        getA11yStatusMessage={getA11yStatusMessage}
-        search
-        getA11ySelectionMessage={getA11ySelectionMessage}
-        noResultsMessage="We couldn't find any matches."
-        placeholder="Start typing a name"
-        items={inputItems}
-      />
-    )
-  }
-}
+const DropdownExample = () => (
+  <Dropdown
+    multiple
+    getA11yStatusMessage={getA11yStatusMessage}
+    search
+    getA11ySelectionMessage={getA11ySelectionMessage}
+    noResultsMessage="We couldn't find any matches."
+    placeholder="Start typing a name"
+    items={inputItems}
+  />
+)
 
 const getA11ySelectionMessage = {
   onAdd: item => `${item.header} has been selected.`,
diff --git a/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchToggleButton.shorthand.tsx b/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchToggleButton.shorthand.tsx
index 1f85c9cc1b..3fb6470421 100644
--- a/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchToggleButton.shorthand.tsx
+++ b/docs/src/examples/components/Dropdown/Variations/DropdownExampleMultipleSearchToggleButton.shorthand.tsx
@@ -13,22 +13,18 @@ const inputItems = [
   'Selina Kyle',
 ]
 
-class DropdownExample extends React.Component {
-  render() {
-    return (
-      <Dropdown
-        multiple
-        getA11yStatusMessage={getA11yStatusMessage}
-        getA11ySelectionMessage={getA11ySelectionMessage}
-        noResultsMessage="We couldn't find any matches."
-        search
-        placeholder="Start typing a name"
-        toggleButton
-        items={inputItems}
-      />
-    )
-  }
-}
+const DropdownExample = () => (
+  <Dropdown
+    multiple
+    getA11yStatusMessage={getA11yStatusMessage}
+    getA11ySelectionMessage={getA11ySelectionMessage}
+    noResultsMessage="We couldn't find any matches."
+    search
+    placeholder="Start typing a name"
+    toggleButton
+    items={inputItems}
+  />
+)
 
 const getA11ySelectionMessage = {
   onAdd: item => `${item} has been selected.`,

From 5882ab8e27bc2a61506f4cb3b359a7edb9969256 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 13:11:15 +0200
Subject: [PATCH 52/62] overriding downshift aria label for the toggle button

---
 src/components/Dropdown/Dropdown.tsx | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 83afe6b3c9..1ac2100cae 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -301,6 +301,7 @@ export default class Dropdown extends AutoControlledComponent<
             onBlur: () => {
               this.setState({ focused: false })
             },
+            'aria-label': content,
           })}
         />
       </Ref>

From 0350af66b3467ae75311a5cadd54c81ac06ea25d Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 13:21:45 +0200
Subject: [PATCH 53/62] made the toggle button arrow non-selectable

---
 src/themes/teams/components/Dropdown/dropdownStyles.ts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index fbf29496cf..a69d19057d 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -87,6 +87,7 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
     display: 'flex',
     justifyContent: 'center',
     alignItems: 'center',
+    userSelect: 'none',
     ...(fluid ? { right: 0 } : { left: `calc(${width} - ${toggleButtonSize})` }),
   }),
 }

From d13c08975963f8db13e1cbdd0ec195411abe70f5 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Thu, 3 Jan 2019 15:29:51 +0200
Subject: [PATCH 54/62] used a lodash util instead of filter

---
 src/components/Dropdown/Dropdown.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 1ac2100cae..46dfe032b6 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -498,7 +498,7 @@ export default class Dropdown extends AutoControlledComponent<
     let filteredItems = items
 
     if (multiple) {
-      filteredItems = filteredItems.filter(item => (value as ShorthandValue[]).indexOf(item) === -1)
+      filteredItems = _.difference(filteredItems, value as ShorthandValue[])
     }
     if (search) {
       if (_.isFunction(search)) {

From 40744a7e4ee213a296a0d72c586e5665739b6f7b Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Fri, 4 Jan 2019 10:59:52 +0200
Subject: [PATCH 55/62] used buttonNode for consistency

---
 src/components/Dropdown/Dropdown.tsx | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 46dfe032b6..6acfd8c61c 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -133,9 +133,9 @@ export default class Dropdown extends AutoControlledComponent<
   Extendable<DropdownProps>,
   DropdownState
 > {
+  private buttonNode: HTMLElement
   private inputNode: HTMLElement
   private listNode: HTMLElement
-  private buttonRef = React.createRef<HTMLElement>()
 
   static displayName = 'Dropdown'
 
@@ -289,7 +289,11 @@ export default class Dropdown extends AutoControlledComponent<
     const content = value && !multiple ? itemToString(value) : placeholder
 
     return (
-      <Ref innerRef={this.buttonRef}>
+      <Ref
+        innerRef={(buttonNode: HTMLElement) => {
+          this.buttonNode = buttonNode
+        }}
+      >
         <Button
           content={content}
           fluid
@@ -664,7 +668,7 @@ export default class Dropdown extends AutoControlledComponent<
         return
       case keyboardKey.Escape:
         accessibilityInputPropsKeyDown(e)
-        this.buttonRef.current.focus()
+        this.buttonNode.focus()
         return
       default:
         accessibilityInputPropsKeyDown(e)
@@ -684,7 +688,7 @@ export default class Dropdown extends AutoControlledComponent<
       this.setA11yStatus(getA11ySelectionMessage.onAdd(item))
     }
     if (!search) {
-      this.buttonRef.current.focus()
+      this.buttonNode.focus()
     }
 
     // we don't have event for it, but want to keep the event handling interface, event is empty.

From 390999af195b09c7dd474c3b04d5ff78a8431b6c Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Fri, 4 Jan 2019 11:22:35 +0200
Subject: [PATCH 56/62] apply tabIndex only if dropdown is non-search

---
 src/components/Dropdown/Dropdown.tsx | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 6acfd8c61c..7c8843bda4 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -374,8 +374,9 @@ export default class Dropdown extends AutoControlledComponent<
     getInputProps: (options?: GetInputPropsOptions) => any,
   ) {
     const accessibilityMenuProps = getMenuProps({ refKey: 'innerRef' }, { suppressRefError: true })
+    const { search } = this.props
     // If it's just a selection, some attributes and listeners from Downshift input need to go on the menu list.
-    if (!this.props.search) {
+    if (!search) {
       const accessibilityInputProps = getInputProps()
       accessibilityMenuProps['aria-activedescendant'] =
         accessibilityInputProps['aria-activedescendant']
@@ -400,7 +401,7 @@ export default class Dropdown extends AutoControlledComponent<
         <List
           {...accessibilityMenuPropsRest}
           styles={styles.list}
-          tabIndex={-1}
+          tabIndex={search ? undefined : -1} // needs to be focused when trigger button is activated.
           aria-hidden={!isOpen}
           items={isOpen ? this.renderItems(styles, variables, getItemProps, highlightedIndex) : []}
         />

From 6c547066936b14df9baa93b3c5d17b370fa0ee91 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Fri, 4 Jan 2019 11:23:19 +0200
Subject: [PATCH 57/62] Revert "used buttonNode for consistency"

This reverts commit 97758c282ca0a694a08a7a913e2bdfe608950f95.
---
 src/components/Dropdown/Dropdown.tsx | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 7c8843bda4..83d6967feb 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -133,9 +133,9 @@ export default class Dropdown extends AutoControlledComponent<
   Extendable<DropdownProps>,
   DropdownState
 > {
-  private buttonNode: HTMLElement
   private inputNode: HTMLElement
   private listNode: HTMLElement
+  private buttonRef = React.createRef<HTMLElement>()
 
   static displayName = 'Dropdown'
 
@@ -289,11 +289,7 @@ export default class Dropdown extends AutoControlledComponent<
     const content = value && !multiple ? itemToString(value) : placeholder
 
     return (
-      <Ref
-        innerRef={(buttonNode: HTMLElement) => {
-          this.buttonNode = buttonNode
-        }}
-      >
+      <Ref innerRef={this.buttonRef}>
         <Button
           content={content}
           fluid
@@ -669,7 +665,7 @@ export default class Dropdown extends AutoControlledComponent<
         return
       case keyboardKey.Escape:
         accessibilityInputPropsKeyDown(e)
-        this.buttonNode.focus()
+        this.buttonRef.current.focus()
         return
       default:
         accessibilityInputPropsKeyDown(e)
@@ -689,7 +685,7 @@ export default class Dropdown extends AutoControlledComponent<
       this.setA11yStatus(getA11ySelectionMessage.onAdd(item))
     }
     if (!search) {
-      this.buttonNode.focus()
+      this.buttonRef.current.focus()
     }
 
     // we don't have event for it, but want to keep the event handling interface, event is empty.

From 0c9767800a61ad8ac2bcb2d2fd048c6d11c69559 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Fri, 4 Jan 2019 12:51:59 +0200
Subject: [PATCH 58/62] refactored the Refs use in Dropdown

---
 src/components/Dropdown/Dropdown.tsx          | 23 +++++++-------
 .../Dropdown/DropdownSearchInput.tsx          | 24 +++++++--------
 src/components/Input/Input.tsx                | 30 ++++++++-----------
 3 files changed, 35 insertions(+), 42 deletions(-)

diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx
index 83d6967feb..98b3183ffc 100644
--- a/src/components/Dropdown/Dropdown.tsx
+++ b/src/components/Dropdown/Dropdown.tsx
@@ -23,6 +23,7 @@ import {
   RenderResultConfig,
   customPropTypes,
   commonPropTypes,
+  handleRef,
 } from '../../lib'
 import keyboardKey from 'keyboard-key'
 import List from '../List/List'
@@ -133,9 +134,9 @@ export default class Dropdown extends AutoControlledComponent<
   Extendable<DropdownProps>,
   DropdownState
 > {
-  private inputNode: HTMLElement
-  private listNode: HTMLElement
   private buttonRef = React.createRef<HTMLElement>()
+  private inputRef = React.createRef<HTMLElement>()
+  private listRef = React.createRef<HTMLElement>()
 
   static displayName = 'Dropdown'
 
@@ -224,7 +225,7 @@ export default class Dropdown extends AutoControlledComponent<
           getA11yStatusMessage={getA11yStatusMessage}
           onStateChange={changes => {
             if (changes.isOpen && !search) {
-              this.listNode.focus()
+              this.listRef.current.focus()
             }
           }}
         >
@@ -330,9 +331,7 @@ export default class Dropdown extends AutoControlledComponent<
         placeholder: noPlaceholder ? '' : placeholder,
         hasToggleButton: !!toggleButton,
         variables,
-        inputRef: (inputNode: HTMLElement) => {
-          this.inputNode = inputNode
-        },
+        inputRef: this.inputRef,
       },
       overrideProps: (predefinedProps: DropdownSearchInputProps) =>
         this.handleSearchInputOverrides(
@@ -389,9 +388,9 @@ export default class Dropdown extends AutoControlledComponent<
     const { innerRef, ...accessibilityMenuPropsRest } = accessibilityMenuProps
     return (
       <Ref
-        innerRef={(listNode: HTMLElement) => {
-          this.listNode = listNode
-          innerRef(listNode)
+        innerRef={(listElement: HTMLElement) => {
+          handleRef(this.listRef, listElement)
+          handleRef(innerRef, listElement)
         }}
       >
         <List
@@ -485,7 +484,7 @@ export default class Dropdown extends AutoControlledComponent<
       case Downshift.stateChangeTypes.blurButton:
         // Downshift closes the list by default on trigger blur. It does not support the case when dropdown is
         // single selection and focuses list on trigger click/up/down/space/enter. Treating that here.
-        if (state.isOpen && document.activeElement === this.listNode) {
+        if (state.isOpen && document.activeElement === this.listRef.current) {
           return {} // won't change state in this case.
         }
       default:
@@ -645,7 +644,7 @@ export default class Dropdown extends AutoControlledComponent<
   }
 
   private handleContainerClick = (isOpen: boolean) => {
-    !isOpen && this.inputNode.focus()
+    !isOpen && this.inputRef.current.focus()
   }
 
   private handleListKeyDown = (
@@ -694,7 +693,7 @@ export default class Dropdown extends AutoControlledComponent<
 
   private handleSelectedItemRemove(e: React.SyntheticEvent, item: ShorthandValue) {
     this.removeItemFromValue(item)
-    this.inputNode.focus()
+    this.inputRef.current.focus()
     e.stopPropagation()
   }
 
diff --git a/src/components/Dropdown/DropdownSearchInput.tsx b/src/components/Dropdown/DropdownSearchInput.tsx
index a6ed33276a..5d967a245d 100644
--- a/src/components/Dropdown/DropdownSearchInput.tsx
+++ b/src/components/Dropdown/DropdownSearchInput.tsx
@@ -10,12 +10,9 @@ import Input from '../Input/Input'
 export interface DropdownSearchInputProps extends UIComponentProps<DropdownSearchInputProps> {
   /** Informs the search input about an existing toggle button. */
   hasToggleButton?: boolean
-  /**
-   * Ref callback with an input DOM node.
-   *
-   * @param {JSX.Element} node - input DOM node.
-   */
-  inputRef?: (inputNode: HTMLElement) => void
+
+  /** Ref for input DOM node. */
+  inputRef?: React.Ref<HTMLElement>
 
   /**
    * Called on input element focus.
@@ -71,7 +68,7 @@ class DropdownSearchInput extends UIComponent<ReactProps<DropdownSearchInputProp
     accessibilityInputProps: PropTypes.object,
     accessibilityComboboxProps: PropTypes.object,
     hasToggleButton: PropTypes.bool,
-    inputRef: PropTypes.func,
+    inputRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
     onFocus: PropTypes.func,
     onInputBlur: PropTypes.func,
     onInputKeyDown: PropTypes.func,
@@ -79,10 +76,6 @@ class DropdownSearchInput extends UIComponent<ReactProps<DropdownSearchInputProp
     placeholder: PropTypes.string,
   }
 
-  private handleInputRef = (inputNode: HTMLElement) => {
-    _.invoke(this.props, 'inputRef', inputNode)
-  }
-
   private handleFocus = (e: React.SyntheticEvent) => {
     _.invoke(this.props, 'onFocus', e, this.props)
   }
@@ -100,10 +93,15 @@ class DropdownSearchInput extends UIComponent<ReactProps<DropdownSearchInputProp
   }
 
   public renderComponent({ rest, styles }: RenderResultConfig<DropdownSearchInputProps>) {
-    const { accessibilityComboboxProps, accessibilityInputProps, placeholder } = this.props
+    const {
+      accessibilityComboboxProps,
+      accessibilityInputProps,
+      inputRef,
+      placeholder,
+    } = this.props
     return (
       <Input
-        inputRef={this.handleInputRef}
+        inputRef={inputRef}
         onFocus={this.handleFocus}
         onKeyUp={this.handleKeyUp}
         wrapper={{
diff --git a/src/components/Input/Input.tsx b/src/components/Input/Input.tsx
index 8eee55fa30..73da8e5f84 100644
--- a/src/components/Input/Input.tsx
+++ b/src/components/Input/Input.tsx
@@ -11,6 +11,7 @@ import {
   UIComponentProps,
   ChildrenComponentProps,
   commonPropTypes,
+  handleRef,
 } from '../../lib'
 import { ReactProps, ShorthandValue, ComponentEventHandler } from '../../../types/utils'
 import Icon from '../Icon/Icon'
@@ -50,12 +51,8 @@ export interface InputProps extends UIComponentProps, ChildrenComponentProps {
   /** The HTML input type. */
   type?: string
 
-  /**
-   * Ref callback with an input DOM node.
-   *
-   * @param {JSX.Element} node - input DOM node.
-   */
-  inputRef?: (node: HTMLElement) => void
+  /** Ref for input DOM node. */
+  inputRef?: React.Ref<HTMLElement>
 
   /** The value of the input. */
   value?: React.ReactText
@@ -77,7 +74,7 @@ export interface InputState {
  *  - if input is search, then use "role='search'"
  */
 class Input extends AutoControlledComponent<ReactProps<InputProps>, InputState> {
-  private inputDomElement: HTMLInputElement
+  private inputRef = React.createRef<HTMLElement>()
 
   static className = 'ui-input'
 
@@ -93,7 +90,7 @@ class Input extends AutoControlledComponent<ReactProps<InputProps>, InputState>
     icon: customPropTypes.itemShorthand,
     iconPosition: PropTypes.oneOf(['start', 'end']),
     input: customPropTypes.itemShorthand,
-    inputRef: PropTypes.func,
+    inputRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
     inline: PropTypes.bool,
     onChange: PropTypes.func,
     type: PropTypes.string,
@@ -116,7 +113,7 @@ class Input extends AutoControlledComponent<ReactProps<InputProps>, InputState>
     styles,
     variables,
   }: RenderResultConfig<InputProps>) {
-    const { className, input, type, wrapper } = this.props
+    const { className, input, inputRef, type, wrapper } = this.props
     const { value = '' } = this.state
     const [htmlInputProps, rest] = partitionHTMLProps(restProps)
 
@@ -125,7 +122,12 @@ class Input extends AutoControlledComponent<ReactProps<InputProps>, InputState>
         className: cx(Input.className, className),
         children: (
           <>
-            <Ref innerRef={this.handleInputRef}>
+            <Ref
+              innerRef={(inputElement: HTMLElement) => {
+                handleRef(this.inputRef, inputElement)
+                handleRef(inputRef, inputElement)
+              }}
+            >
               {Slot.create(input || type, {
                 defaultProps: {
                   ...htmlInputProps,
@@ -155,16 +157,10 @@ class Input extends AutoControlledComponent<ReactProps<InputProps>, InputState>
     })
   }
 
-  private handleInputRef = (inputNode: HTMLElement) => {
-    this.inputDomElement = inputNode as HTMLInputElement
-
-    _.invoke(this.props, 'inputRef', inputNode)
-  }
-
   private handleIconOverrides = predefinedProps => ({
     onClick: (e: React.SyntheticEvent) => {
       this.handleOnClear()
-      this.inputDomElement.focus()
+      this.inputRef.current.focus()
       _.invoke(predefinedProps, 'onClick', e, this.props)
     },
     ...(predefinedProps.onClick && { tabIndex: '0' }),

From 49962603f79e529e24f8b052280efe6bae9d759f Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Fri, 4 Jan 2019 15:15:45 +0200
Subject: [PATCH 59/62] updated changelog

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa76ff2292..a401fc3cdb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -45,6 +45,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
 - Add `color` prop to `Icon` component @Bugaa92 ([#651](https://github.com/stardust-ui/react/pull/651))
 - Create a `base` theme with Text component example @almedint ([#618](https://github.com/stardust-ui/react/pull/618))
 - Adding attachment behavior to handle space/enter key @kolaps33 ([#375](https://github.com/stardust-ui/react/pull/375))
+- Add Dropdown Single Selection variant @silviuavram ([#584](https://github.com/stardust-ui/react/pull/584))
 
 ### Documentation
 - Add more accessibility descriptions to components and behaviors @jurokapsiar  ([#648](https://github.com/stardust-ui/react/pull/648))

From 2b7f913171ca02eb56f5157f604e5ca5c490f09b Mon Sep 17 00:00:00 2001
From: manajdov <manajdov@microsoft.com>
Date: Tue, 8 Jan 2019 11:46:38 +0100
Subject: [PATCH 60/62] -added white background on the list in the Dropdown for
 fixing transparent scrollbar

---
 src/themes/teams/components/Dropdown/dropdownStyles.ts    | 6 +++++-
 src/themes/teams/components/Dropdown/dropdownVariables.ts | 2 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/themes/teams/components/Dropdown/dropdownStyles.ts b/src/themes/teams/components/Dropdown/dropdownStyles.ts
index a69d19057d..f06a82774f 100644
--- a/src/themes/teams/components/Dropdown/dropdownStyles.ts
+++ b/src/themes/teams/components/Dropdown/dropdownStyles.ts
@@ -64,13 +64,17 @@ const dropdownStyles: ComponentSlotStylesInput<DropdownProps, DropdownVariables>
     margin: '.4rem 0 0 .4rem',
   }),
 
-  list: ({ variables: { listMaxHeight, width }, props: { fluid } }): ICSSInJSStyle => ({
+  list: ({
+    variables: { listMaxHeight, width, listBackgroundColor },
+    props: { fluid },
+  }): ICSSInJSStyle => ({
     position: 'absolute',
     zIndex: 1000,
     maxHeight: listMaxHeight,
     overflowY: 'auto',
     width: fluid ? '100%' : width,
     top: 'calc(100% + 2px)', // leave room for container + its border
+    background: listBackgroundColor,
   }),
 
   emptyListItem: ({ variables: { listItemBackgroundColor } }) => ({
diff --git a/src/themes/teams/components/Dropdown/dropdownVariables.ts b/src/themes/teams/components/Dropdown/dropdownVariables.ts
index d92e33e739..489bbccc4a 100644
--- a/src/themes/teams/components/Dropdown/dropdownVariables.ts
+++ b/src/themes/teams/components/Dropdown/dropdownVariables.ts
@@ -10,6 +10,7 @@ export interface DropdownVariables {
   comboboxPaddingButton: string
   comboboxPaddingInput: string
   comboboxFlexBasis: string
+  listBackgroundColor: string
   listItemBackgroundColor: string
   listItemBackgroundColorActive: string
   listItemColorActive: string
@@ -31,6 +32,7 @@ export default (siteVars): DropdownVariables => ({
   comboboxPaddingButton: `0 ${_12px_asRem}`,
   comboboxPaddingInput: `${_6px_asRem} ${_12px_asRem}`,
   comboboxFlexBasis: '50px',
+  listBackgroundColor: siteVars.white,
   listItemBackgroundColor: siteVars.white,
   listItemBackgroundColorActive: siteVars.brand,
   listItemColorActive: siteVars.white,

From 5d492294e13dd2d46f1d4cda7aa9047347ae38ca Mon Sep 17 00:00:00 2001
From: manajdov <manajdov@microsoft.com>
Date: Tue, 8 Jan 2019 11:59:17 +0100
Subject: [PATCH 61/62] -fixed changelog

---
 CHANGELOG.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index c875f78b88..071e6b5002 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
 
 ### Features
 - Add `on` and `mouseLeaveDelay` props to `Popup` component @mnajdova ([#622](https://github.com/stardust-ui/react/pull/622))
+- Add Dropdown Single Selection variant @silviuavram ([#584](https://github.com/stardust-ui/react/pull/584))
 
 <!--------------------------------[ v0.16.0 ]------------------------------- -->
 ## [v0.16.0](https://github.com/stardust-ui/react/tree/v0.16.0) (2019-01-07)
@@ -53,7 +54,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
 - Add `color` prop to `Icon` component @Bugaa92 ([#651](https://github.com/stardust-ui/react/pull/651))
 - Create a `base` theme with Text component example @almedint ([#618](https://github.com/stardust-ui/react/pull/618))
 - Adding attachment behavior to handle space/enter key @kolaps33 ([#375](https://github.com/stardust-ui/react/pull/375))
-- Add Dropdown Single Selection variant @silviuavram ([#584](https://github.com/stardust-ui/react/pull/584))
 
 ### Documentation
 - Add more accessibility descriptions to components and behaviors @jurokapsiar  ([#648](https://github.com/stardust-ui/react/pull/648))

From f17b5b194dcea618aad7c48097ecc83fb6bccc18 Mon Sep 17 00:00:00 2001
From: Silviu Avram <siavram@microsoft.com>
Date: Tue, 8 Jan 2019 15:28:41 +0100
Subject: [PATCH 62/62] removed '.shorthand' from examplePath

---
 docs/src/examples/components/Dropdown/Types/index.tsx      | 4 ++--
 docs/src/examples/components/Dropdown/Variations/index.tsx | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/docs/src/examples/components/Dropdown/Types/index.tsx b/docs/src/examples/components/Dropdown/Types/index.tsx
index dc2a7499ef..9b11169a48 100644
--- a/docs/src/examples/components/Dropdown/Types/index.tsx
+++ b/docs/src/examples/components/Dropdown/Types/index.tsx
@@ -7,12 +7,12 @@ const Types = () => (
     <ComponentExample
       title="Single Selection"
       description="A dropdown with single selection."
-      examplePath="components/Dropdown/Types/DropdownExampleSingleSelection.shorthand"
+      examplePath="components/Dropdown/Types/DropdownExampleSingleSelection"
     />
     <ComponentExample
       title="Multiple Search"
       description="A dropdown with multiple selection and search."
-      examplePath="components/Dropdown/Types/DropdownExampleMultipleSearch.shorthand"
+      examplePath="components/Dropdown/Types/DropdownExampleMultipleSearch"
     />
   </ExampleSection>
 )
diff --git a/docs/src/examples/components/Dropdown/Variations/index.tsx b/docs/src/examples/components/Dropdown/Variations/index.tsx
index cd3ff955f8..ca3ecfd32f 100644
--- a/docs/src/examples/components/Dropdown/Variations/index.tsx
+++ b/docs/src/examples/components/Dropdown/Variations/index.tsx
@@ -7,17 +7,17 @@ const Variations = () => (
     <ComponentExample
       title="Multiple Search with Image and Content"
       description="A multiple search dropdown which items have header, content and image."
-      examplePath="components/Dropdown/Variations/DropdownExampleMultipleSearchImageAndContent.shorthand"
+      examplePath="components/Dropdown/Variations/DropdownExampleMultipleSearchImageAndContent"
     />
     <ComponentExample
       title="Multiple Search Fluid"
       description="A multiple search dropdown that fits the width of the container."
-      examplePath="components/Dropdown/Variations/DropdownExampleMultipleSearchFluid.shorthand"
+      examplePath="components/Dropdown/Variations/DropdownExampleMultipleSearchFluid"
     />
     <ComponentExample
       title="Multiple Search with Toggle Button"
       description="A multiple search dropdown with toggle button that shows/hides the items list."
-      examplePath="components/Dropdown/Variations/DropdownExampleMultipleSearchToggleButton.shorthand"
+      examplePath="components/Dropdown/Variations/DropdownExampleMultipleSearchToggleButton"
     />
   </ExampleSection>
 )