Bug 1601748 - Improve the UI of the messenger compose recipient area. r=mkmelin, ui-r=paenglab
authorAlessandro Castellani <alessandro@thunderbird.net>
Mon, 06 Jan 2020 12:48:37 -0800
changeset 37919 c21622941d4bc9a922cf046ced1e1c4d86b31590
parent 37918 e60c7640c9731b8be5780ceb72ad3c83784958cb
child 37920 3daf6e6b3f9e60b609a965afc5ffb30e204f5bad
push id398
push userclokep@gmail.com
push dateMon, 09 Mar 2020 19:10:28 +0000
reviewersmkmelin, paenglab
bugs1601748
Bug 1601748 - Improve the UI of the messenger compose recipient area. r=mkmelin, ui-r=paenglab
mail/base/content/mailWidgets.js
mail/components/compose/content/MsgComposeCommands.js
mail/components/compose/content/addressingWidgetOverlay.js
mail/components/compose/content/messengercompose.xhtml
mail/locales/en-US/chrome/messenger/messengercompose/messengercompose.dtd
mail/test/browser/composition/browser_addressWidgets.js
mail/test/browser/composition/browser_sendButton.js
mail/themes/shared/jar.inc.mn
mail/themes/shared/mail/icons/overflow.svg
mail/themes/shared/mail/messengercompose.css
--- a/mail/base/content/mailWidgets.js
+++ b/mail/base/content/mailWidgets.js
@@ -2376,16 +2376,17 @@
       for (let item of this.getAllSelectedPills()) {
         item.remove();
       }
 
       pill.originalInput.focus();
       pill.remove();
 
       onRecipientsChanged();
+      calculateHeaderHeight();
     }
 
     /**
      * Move the focus on the first pill from the same .address-container.
      *
      * @param {XULElement} pill - The mail-address-pill element.
      */
     setFocusOnFirstPill(pill) {
--- a/mail/components/compose/content/MsgComposeCommands.js
+++ b/mail/components/compose/content/MsgComposeCommands.js
@@ -7,16 +7,18 @@
 /* import-globals-from ../../../../mailnews/addrbook/content/abDragDrop.js */
 /* import-globals-from ../../../base/content/mailCore.js */
 /* import-globals-from ../../../base/content/utilityOverlay.js */
 /* import-globals-from addressingWidgetOverlay.js */
 /* import-globals-from ComposerCommands.js */
 /* import-globals-from editor.js */
 /* import-globals-from editorUtilities.js */
 
+/* global updateRecipientsPanelVisibility */
+
 /**
  * Commands for the message composition window.
  */
 
 // Ensure the activity modules are loaded for this window.
 ChromeUtils.import("resource:///modules/activity/activityModules.jsm");
 var { AttachmentChecker } = ChromeUtils.import(
   "resource:///modules/AttachmentChecker.jsm"
@@ -3404,33 +3406,33 @@ function ComposeLoad() {
 
   try {
     SetupCommandUpdateHandlers();
     // This will do migration, or create a new account if we need to.
     // We also want to open the account wizard if no identities are found
     let state = verifyAccounts(WizCallback, true);
 
     if (otherHeaders) {
-      let addressingWidgetLabels = document.getElementById(
-        "addressingWidgetLabels"
+      let extraRecipientsPanel = document.getElementById(
+        "extraRecipientsPanel"
       );
       let recipientsContainer = document.getElementById("recipientsContainer");
 
       for (let header of otherHeaders.split(",")) {
         let recipient = {
           id: `${header}AddrInput`,
           row: `addressRow${header}`,
           label: `${header}AddrLabel`,
           labelId: header,
           container: `${header}AddrContainer`,
           class: "nntp-input",
           type: "addr_other",
         };
 
-        addressingWidgetLabels.appendChild(createRecipientLabel(header));
+        extraRecipientsPanel.appendChild(createRecipientLabel(header));
         recipientsContainer.appendChild(
           recipientsContainer.buildRecipientRows(recipient)
         );
       }
     }
     if (state) {
       ComposeStartup(null);
     }
@@ -3521,33 +3523,29 @@ function SetDocumentCharacterSet(aCharse
  * Create the recipient label to add in the messenger compose dialog.
  *
  * @param {string} labelID - The unique identifier of the email header.
  * @returns {XULelement} The newly create XUL label.
  */
 function createRecipientLabel(labelID) {
   let label = document.createXULElement("label");
   label.setAttribute("id", labelID);
-  label.textContent = labelID;
+  label.setAttribute("value", labelID);
 
   label.addEventListener("click", () => {
     showAddressRow(label, `addressRow${labelID}`);
   });
   label.addEventListener("keypress", event => {
     showAddressRowKeyPress(event, label, `addressRow${labelID}`);
   });
   label.setAttribute("control", `${labelID}AddrInput`);
 
   // Necessary to allow focus via TAB key.
   label.setAttribute("tabindex", 0);
 
-  let newImage = document.createXULElement("image");
-  newImage.classList.add("new-icon");
-  label.prepend(newImage);
-
   return label;
 }
 
 /**
  * Return the full display string for any non-default text encoding of the
  * current composition (friendly name plus official character set name).
  * For the default text encoding, return empty string (""), to reduce
  * ux-complexity, e.g. for the default Status Bar display.
@@ -6250,16 +6248,18 @@ function hideIrrelevantAddressingOptions
       hideNews = false;
     }
   }
   // If there is no News (NNTP) account existing then
   // hide the Newsgroup and Followup-To recipient type in all the menulists.
   for (let item of document.querySelectorAll(".nntp-label")) {
     item.collapsed = hideNews;
   }
+
+  updateRecipientsPanelVisibility();
 }
 
 function LoadIdentity(startup) {
   var identityElement = document.getElementById("msgIdentity");
   var prevIdentity = gCurrentIdentity;
 
   if (identityElement) {
     let idKey = null;
--- a/mail/components/compose/content/addressingWidgetOverlay.js
+++ b/mail/components/compose/content/addressingWidgetOverlay.js
@@ -633,16 +633,18 @@ function showAddressRowKeyPress(event, l
  */
 function showAddressRow(label, rowID) {
   let container = document.getElementById(rowID);
   let input = container.querySelector(`input[is="autocomplete-input"]`);
 
   container.classList.remove("hidden");
   label.setAttribute("collapsed", "true");
   input.focus();
+
+  updateRecipientsPanelVisibility();
 }
 
 /**
  * Hide the container row of a recipient (Cc, Bcc, etc.).
  * The container can't be hidden if previously typed addresses are listed.
  *
  * @param {XULelement} element - The clicked label.
  * @param {string} labelID - The ID of the label to show.
@@ -675,29 +677,63 @@ function hideAddressRow(element, labelID
   // Reset the original input.
   let input = container.querySelector(`input[is="autocomplete-input"]`);
   input.value = "";
 
   container.classList.add("hidden");
   document.getElementById(labelID).removeAttribute("collapsed");
 
   onRecipientsChanged();
+  updateRecipientsPanelVisibility();
 }
 
 /**
  * Calculate the height of the composer header area every time a pill is created.
  * If the height is bigger than 2/3 of the compose window heigh, enable overflow.
  */
 function calculateHeaderHeight() {
-  let container = document.getElementById("msgheaderstoolbar-box");
-  if (container.classList.contains("overflow")) {
+  let container = document.getElementById("recipientsContainer");
+  if (
+    container.classList.contains("overflow") &&
+    container.scrollHeight >= window.outerHeight * 0.7
+  ) {
+    return;
+  }
+
+  let header = document.getElementById("headers-box");
+  if (
+    container.classList.contains("overflow") &&
+    container.scrollHeight < window.outerHeight * 0.7
+  ) {
+    container.classList.remove("overflow");
+    header.removeAttribute("height");
     return;
   }
 
   if (container.clientHeight >= window.outerHeight * 0.7) {
-    document.getElementById("recipientsContainer").classList.add("overflow");
+    container.classList.add("overflow");
 
-    let header = document.getElementById("headers-box");
     if (!header.hasAttribute("height")) {
       header.setAttribute("height", 300);
     }
   }
 }
+
+/**
+ * Show the #extraRecipientsPanel.
+ *
+ * @param {Event} event - The DOM event.
+ */
+function showExtraRecipients(event) {
+  let panel = document.getElementById("extraRecipientsPanel");
+  panel.openPopup(event.originalTarget, "after_end", -8, 0, true);
+}
+
+/**
+ * Hide or show the panel and overflow button for the extra recipients
+ * based on the currently available labels.
+ */
+function updateRecipientsPanelVisibility() {
+  document.getElementById("extraRecipientsLabel").collapsed =
+    document
+      .getElementById("extraRecipientsPanel")
+      .querySelectorAll('label:not([collapsed="true"])').length == 0;
+}
--- a/mail/components/compose/content/messengercompose.xhtml
+++ b/mail/components/compose/content/messengercompose.xhtml
@@ -583,16 +583,33 @@
                  label-AZ="&sortAttachmentsPanelBtn.Sort.AZ.label;"
                  label-ZA="&sortAttachmentsPanelBtn.Sort.ZA.label;"
                  label-selection-AZ="&sortAttachmentsPanelBtn.SortSelection.AZ.label;"
                  label-selection-ZA="&sortAttachmentsPanelBtn.SortSelection.ZA.label;"
                  key="key_sortAttachmentsToggle"
                  command="cmd_sortAttachmentsToggle"/>
 </panel>
 
+<panel id="extraRecipientsPanel" type="arrow" orient="vertical"
+       onkeypress="if (event.key == 'Enter') { this.hidePopup(); }"
+       onclick="this.hidePopup();">
+  <label id="addr_reply" value="&replyAddr2.label;"
+         onclick="showAddressRow(this, 'addressRowReply')"
+         onkeypress="showAddressRowKeyPress(event, this, 'addressRowReply')"
+         control="replyAddrInput" class="recipient-label"/>
+  <label id="addr_newsgroups" value="&newsgroupsAddr2.label;"
+         onclick="showAddressRow(this, 'addressRowNewsgroups')"
+         onkeypress="showAddressRowKeyPress(event, this, 'addressRowNewsgroups')"
+         control="newsgroupsAddrInput" class="nntp-label recipient-label"/>
+  <label id="addr_followup" value="&followupAddr2.label;"
+         onclick="showAddressRow(this, 'addressRowFollowup')"
+         onkeypress="showAddressRowKeyPress(event, this, 'addressRowFollowup')"
+         control="followupAddrInput" class="nntp-label recipient-label"/>
+</panel>
+
 <menupopup id="msgComposeContext"
            onpopupshowing="if (event.target != this) { return true; } openEditorContextMenu(this);">
 
   <!-- Spellchecking menu items -->
   <menuitem id="spellCheckNoSuggestions" label="&spellNoSuggestions.label;" disabled="true"/>
   <menuseparator id="spellCheckAddSep" />
   <menuitem id="spellCheckAddToDictionary" label="&spellAddToDictionary.label;" accesskey="&spellAddToDictionary.accesskey;"
             oncommand="gSpellChecker.addToDictionary();"/>
@@ -1989,29 +2006,53 @@
              persist="collapsed"
              flex="1"
              customizable="true" nowindowdrag="true"
              ondragover="nsDragAndDrop.dragOver(event, envelopeDragObserver);"
              ondrop="nsDragAndDrop.drop(event, envelopeDragObserver);"
              ondragexit="nsDragAndDrop.dragExit(event, envelopeDragObserver);">
       <hbox id="msgheaderstoolbar-box" flex="1">
         <vbox flex="1" id="addresses-box">
-          <hbox id="top-gradient-box">
+          <hbox id="top-gradient-box" class="address-identity-recipient">
             <hbox class="aw-firstColBox"/>
             <hbox id="identityLabel-box" align="center"
                   pack="end" style="&headersSpace2.style;">
               <label id="identityLabel" value="&fromAddr2.label;"
                      accesskey="&fromAddr.accesskey;" control="msgIdentity"/>
             </hbox>
             <menulist is="menulist-editable" id="msgIdentity"
                       type="description" flex="1"
                       disableautoselect="true" onkeypress="fromKeyPress(event);"
                       oncommand="LoadIdentity(false);" disableonsend="true">
               <menupopup id="msgIdentityPopup"/>
             </menulist>
+
+            <hbox class="addressingWidgetItem">
+              <hbox id="addressingWidgetLabels" class="address-extra-recipients"
+                    flex="1" align="center">
+                <label id="addr_to" control="toAddrInput" hidden="true"/>
+                <label id="addr_cc" value="&ccAddr2.label;"
+                       onclick="showAddressRow(this, 'addressRowCc')"
+                       onkeypress="showAddressRowKeyPress(event, this, 'addressRowCc')"
+                       control="ccAddrInput" class="recipient-label"/>
+                <label id="addr_bcc" value="&bccAddr2.label;"
+                       onclick="showAddressRow(this, 'addressRowBcc')"
+                       onkeypress="showAddressRowKeyPress(event, this, 'addressRowBcc')"
+                       control="bccAddrInput" class="recipient-label"/>
+
+                <label id="extraRecipientsLabel"
+                       onclick="showExtraRecipients(event);"
+                       tooltiptext="&extraRecipients.tooltip;"
+                       class="extra-recipients-label"
+                       onkeypress="if (event.key == 'Enter') { showExtraRecipients(event); }">
+                    <image class="overflow-icon"/>
+                </label>
+
+              </hbox>
+            </hbox>
           </hbox>
 
           <mail-recipients-area id="recipientsContainer" orient="vertical"
                                 class="recipients-container" flex="1">
             <hbox id="addressRowTo" class="addressingWidgetItem address-row">
               <hbox class="aw-firstColBox"/>
               <hbox class="address-label-container" align="top" pack="end"
                     style="&headersSpace2.style;">
@@ -2224,50 +2265,16 @@
                             onblur="resetAddressContainer(this);"
                             onkeypress="recipientKeyPress(event, this);"
                             recipienttype="addr_followup"
                             size="1"/>
               </hbox>
             </hbox>
           </mail-recipients-area>
 
-          <hbox class="addressingWidgetItem">
-            <hbox class="aw-firstColBox"/>
-            <hbox class="address-label-container" style="&headersSpace2.style;"/>
-            <hbox id="addressingWidgetLabels" class="address-extra-recipients"
-                  flex="1" align="center">
-              <label id="addr_to" control="toAddrInput" hidden="true"/>
-              <label id="addr_cc" onclick="showAddressRow(this, 'addressRowCc')"
-                     onkeypress="showAddressRowKeyPress(event, this, 'addressRowCc')"
-                     control="ccAddrInput">
-                <image class="new-icon"/>&ccAddr2.label;
-              </label>
-              <label id="addr_bcc" onclick="showAddressRow(this, 'addressRowBcc')"
-                     onkeypress="showAddressRowKeyPress(event, this, 'addressRowBcc')"
-                     control="bccAddrInput">
-                <image class="new-icon"/>&bccAddr2.label;
-              </label>
-              <label id="addr_reply" onclick="showAddressRow(this, 'addressRowReply')"
-                     onkeypress="showAddressRowKeyPress(event, this, 'addressRowReply')"
-                     control="replyAddrInput">
-                <image class="new-icon"/>&replyAddr2.label;
-              </label>
-              <label id="addr_newsgroups" onclick="showAddressRow(this, 'addressRowNewsgroups')"
-                     onkeypress="showAddressRowKeyPress(event, this, 'addressRowNewsgroups')"
-                     control="newsgroupsAddrInput" class="nntp-label">
-                <image class="new-icon"/>&newsgroupsAddr2.label;
-              </label>
-              <label id="addr_followup" onclick="showAddressRow(this, 'addressRowFollowup')"
-                     onkeypress="showAddressRowKeyPress(event, this, 'addressRowFollowup')"
-                     control="followupAddrInput" class="nntp-label">
-                <image class="new-icon"/>&followupAddr2.label;
-              </label>
-            </hbox>
-          </hbox>
-
           <hbox id="subject-box">
             <hbox class="aw-firstColBox"/>
             <hbox id="subjectLabel-box" align="center"
                   pack="end" style="&headersSpace2.style;">
               <label id="subjectLabel" value="&subject2.label;"
                      accesskey="&subject.accesskey;" control="msgSubject"/>
             </hbox>
             <hbox flex="1" align="center" class="input-container">
--- a/mail/locales/en-US/chrome/messenger/messengercompose/messengercompose.dtd
+++ b/mail/locales/en-US/chrome/messenger/messengercompose/messengercompose.dtd
@@ -245,16 +245,17 @@
 <!ENTITY copyButton.tooltip             "Copy">
 <!ENTITY pasteButton.tooltip            "Paste">
 <!ENTITY printButton.tooltip "Print this message">
 
 <!-- Headers -->
 <!--LOCALIZATION NOTE headersSpaces.style is for aligning  the From:, To: and
     Subject: rows. It should be larger than the largest Header label  -->
 <!ENTITY headersSpace2.style "width: 8em;">
+<!ENTITY extraRecipients.tooltip "Other types of addressing fields">
 <!ENTITY fromAddr2.label "From">
 <!ENTITY fromAddr.accesskey "r">
 <!ENTITY toAddr2.label "To">
 <!ENTITY ccAddr2.label "Cc">
 <!ENTITY bccAddr2.label "Bcc">
 <!ENTITY replyAddr2.label "Reply-To">
 <!ENTITY newsgroupsAddr2.label "Newsgroup">
 <!ENTITY followupAddr2.label "Followup-To">
--- a/mail/test/browser/composition/browser_addressWidgets.js
+++ b/mail/test/browser/composition/browser_addressWidgets.js
@@ -46,17 +46,17 @@ add_task(function setupModule(module) {
 });
 
 /**
  * Check if the address type items are in the wished state.
  *
  * @param aItemsEnabled  List of item values that should be enabled (uncollapsed).
  */
 function check_address_types_state(aItemsEnabled) {
-  let addr_types = cwc.e("addressingWidgetLabels").querySelectorAll("label");
+  let addr_types = document.querySelectorAll("label.recipient-label");
   for (let item of addr_types) {
     Assert.ok(item.collapsed != aItemsEnabled.includes(item.id));
   }
 }
 
 /**
  * With only a POP3 account, no News related address types should be enabled.
  */
--- a/mail/test/browser/composition/browser_sendButton.js
+++ b/mail/test/browser/composition/browser_sendButton.js
@@ -20,16 +20,17 @@ var {
 } = ChromeUtils.import(
   "resource://testing-common/mozmill/AddressBookHelpers.jsm"
 );
 var {
   be_in_folder,
   click_tree_row,
   FAKE_SERVER_HOSTNAME,
   get_special_folder,
+  wait_for_popup_to_open,
 } = ChromeUtils.import(
   "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
 );
 var {
   clear_recipient,
   get_first_pill,
   close_compose_window,
   open_compose_new_mail,
@@ -86,25 +87,29 @@ function check_send_commands_state(aCwc,
 
 /**
  * Bug 431217
  * Test that the Send buttons are properly enabled if an addressee is input
  * by the user.
  */
 add_task(function test_send_enabled_manual_address() {
   let cwc = open_compose_new_mail(); // compose controller
+  let panel = cwc.e("extraRecipientsPanel"); // extra recipients panel
+
   // On an empty window, Send must be disabled.
   check_send_commands_state(cwc, false);
 
   // On valid "To:" addressee input, Send must be enabled.
   setup_msg_contents(cwc, " recipient@fake.invalid ", "", "");
   check_send_commands_state(cwc, true);
 
   // When the addressee is not in To, Cc, Bcc or Newsgroup, disable Send again.
   clear_recipient(cwc);
+  cwc.click(cwc.eid("extraRecipientsLabel"));
+  wait_for_popup_to_open(panel);
   cwc.click(cwc.eid("addr_reply"));
   setup_msg_contents(cwc, " recipient@fake.invalid ", "", "", "replyAddrInput");
   check_send_commands_state(cwc, false);
 
   clear_recipient(cwc);
   check_send_commands_state(cwc, false);
 
   // Bug 1296535
@@ -149,16 +154,22 @@ add_task(function test_send_enabled_manu
   check_send_commands_state(cwc, false);
 
   setup_msg_contents(cwc, "emptyList <list> ", "", "");
   check_send_commands_state(cwc, true);
 
   clear_recipient(cwc);
   check_send_commands_state(cwc, false);
 
+  // Show the extraRecipientsLabel in order to trigger the opening og the
+  // extraRecipientsPanel.
+  cwc.e("extraRecipientsLabel").removeAttribute("collapsed");
+  cwc.click(cwc.eid("extraRecipientsLabel"));
+  wait_for_popup_to_open(panel);
+
   // - some string as a newsgroup
   cwc.e("addr_newsgroups").removeAttribute("collapsed");
   cwc.click(cwc.eid("addr_newsgroups"));
   setup_msg_contents(cwc, "newsgroup ", "", "", "newsgroupsAddrInput");
   check_send_commands_state(cwc, true);
 
   close_compose_window(cwc);
 });
--- a/mail/themes/shared/jar.inc.mn
+++ b/mail/themes/shared/jar.inc.mn
@@ -68,16 +68,17 @@
   skin/classic/messenger/icons/move-top.svg                   (../shared/mail/icons/move-top.svg)
   skin/classic/messenger/icons/move-up.svg                    (../shared/mail/icons/move-up.svg)
   skin/classic/messenger/icons/navigation.svg                 (../shared/mail/icons/navigation.svg)
   skin/classic/messenger/icons/new.svg                        (../shared/mail/icons/new.svg)
   skin/classic/messenger/icons/newmsg.svg                     (../shared/mail/icons/newmsg.svg)
   skin/classic/messenger/icons/nextmsg.svg                    (../shared/mail/icons/nextmsg.svg)
   skin/classic/messenger/icons/nextunread.svg                 (../shared/mail/icons/nextunread.svg)
   skin/classic/messenger/icons/overflow-indicator.png         (../shared/mail/icons/overflow-indicator.png)
+  skin/classic/messenger/icons/overflow.svg                   (../shared/mail/icons/overflow.svg)
   skin/classic/messenger/icons/paste.svg                      (../shared/mail/icons/paste.svg)
   skin/classic/messenger/icons/pluginBlocked.svg              (../shared/mail/icons/pluginBlocked.svg)
   skin/classic/messenger/icons/previousmsg.svg                (../shared/mail/icons/previousmsg.svg)
   skin/classic/messenger/icons/previousunread.svg             (../shared/mail/icons/previousunread.svg)
   skin/classic/messenger/icons/print.svg                      (../shared/mail/icons/print.svg)
   skin/classic/messenger/icons/panel-icon-magnifier.svg       (../shared/mail/icons/panel-icon-magnifier.svg)
   skin/classic/messenger/icons/quit.svg                       (../shared/mail/icons/quit.svg)
   skin/classic/messenger/icons/quote.svg                      (../shared/mail/icons/quote.svg)
new file mode 100644
--- /dev/null
+++ b/mail/themes/shared/mail/icons/overflow.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="context-fill" d="M8.707 7.293l-5-5a1 1 0 0 0-1.414 1.414L6.586 8l-4.293 4.293a1 1 0 1 0 1.414 1.414l5-5a1 1 0 0 0 0-1.414zm6 0l-5-5a1 1 0 0 0-1.414 1.414L12.586 8l-4.293 4.293a1 1 0 1 0 1.414 1.414l5-5a1 1 0 0 0 0-1.414z"></path></svg>
--- a/mail/themes/shared/mail/messengercompose.css
+++ b/mail/themes/shared/mail/messengercompose.css
@@ -462,17 +462,17 @@
   margin-inline-end: 6px;
   text-align: right;
 }
 
 #msgIdentity {
   -moz-appearance: none;
   -moz-box-align: center;
   font: inherit;
-  margin-inline-end: 8px;
+  margin-inline-end: 0;
   border: 1px solid var(--toolbarbutton-hover-bordercolor);
   border-radius: 2px;
   background-color: -moz-field;
   -moz-context-properties: fill;
   fill: currentColor;
   transition: border .2s, box-shadow .2s;
 }
 
@@ -496,17 +496,17 @@
 
 .recipients-container.overflow {
   overflow-y: auto;
 }
 
 .address-row {
   display: flex;
   flex: 1;
-  margin-block: 5px;
+  margin-block: 6px;
   margin-inline-end: 8px;
   align-items: self-start;
 }
 
 .address-row > .aw-firstColBox {
   transition: opacity .2s ease;
   opacity: 0;
 }
@@ -628,65 +628,96 @@
 .address-pill.warning[selected]:not(.editing),
 #MsgHeadersToolbar[brighttext] .address-pill.warning[selected]:not(.editing),
 .address-pill.error[selected]:not(.editing),
 #MsgHeadersToolbar[brighttext] .address-pill.error[selected]:not(.editing) {
   color: HighlightText;
   background-color: Highlight;
 }
 
-.address-extra-recipients {
+.address-identity-recipient {
   margin-inline-end: 8px;
 }
 
 .address-extra-recipients label {
-  margin-top: 0;
-  margin-bottom: 6px;
+  margin-block: 0;
+  margin-inline: 12px 6px;
   transition: color 0.2s;
-  margin-inline-end: 12px;
+  line-height: 1;
 }
 
-.new-icon {
+.overflow-icon {
   -moz-appearance: none;
   -moz-context-properties: fill, fill-opacity;
-  list-style-image: url(chrome://messenger/skin/icons/new.svg);
+  list-style-image: url(chrome://messenger/skin/icons/overflow.svg);
   color: inherit !important;
   fill: currentColor;
   fill-opacity: 1;
   width: 15px;
-  height: 15px;
-  background-color: rgba(0,0,0,0.1);
-  border-radius: 50%;
-  padding: 3px;
-  vertical-align: sub;
-  display: inline-block;
-  margin-inline-end: 4px;
+}
+
+label.extra-recipients-label {
+  border-radius: 2px;
+  padding: 2px;
+  width: 16px;
+  height: 16px;
+  margin-inline: 6px;
+}
+
+.extra-recipients-label:hover,
+.extra-recipients-label:focus {
+  cursor: pointer;
+  background-color: var(--toolbarbutton-hover-background);
+}
+
+.extra-recipients-label image {
+  display: inline;
+  vertical-align: middle;
 }
 
-#MsgHeadersToolbar[brighttext] .new-icon {
-  background-color: rgba(255, 255, 255, 0.1);
+.address-extra-recipients label:hover:not(.extra-recipients-label),
+.aw-firstColBox label:hover:not(.extra-recipients-label) {
+  cursor: pointer;
+  color: Highlight;
+}
+
+#extraRecipientsPanel {
+  min-width: 160px;
+  --arrowpanel-padding: 0;
 }
 
-.address-extra-recipients label:hover,
-.aw-firstColBox label:hover {
+#extraRecipientsPanel label {
+  padding: 4px 8px;
+  margin: 2px 0;
+  width: 100%;
   cursor: pointer;
-  color: Highlight;
+  transition: background-color 0.2s;
+}
+
+#extraRecipientsPanel label:hover,
+#extraRecipientsPanel label:focus {
+  background-color: var(--arrowpanel-dimmed);
+}
+
+#extraRecipientsPanel label:hover:active {
+  background-color: var(--arrowpanel-dimmed-further);
+  box-shadow: 0 1px 0 hsla(210, 4%, 10%, .03) inset;
 }
 
 .aw-firstColBox label:hover .close-icon {
   fill-opacity: 0.1;
 }
 
 .aw-firstColBox label {
   margin-top: 4px;
   margin-bottom: 0;
 }
 
-.address-extra-recipients label:focus:not(:hover),
-.aw-firstColBox label:focus:not(:hover) image {
+.address-extra-recipients label:focus:not(:hover):not(.extra-recipients-label),
+.aw-firstColBox label:focus:not(:hover):not(.extra-recipients-label) image {
   outline: 2px dashed Highlight;
 }
 
 #msgIdentity:hover,
 #msgSubject:hover,
 .address-container:hover  {
   border-color: rgba(0,0,0,0.5);
 }