[ntp-history] Actionable header tile

A follow up will address the entire header tile being focusable when
the suggestion chip feature flag is false.

Demo:
Narrow modules:
https://drive.google.com/file/d/1AclQjcAOZH1_dZRrrHIccQIJLdqvUFZw/view

Screenshots:
https://drive.google.com/corp/drive/u/0/folders/1i3eicOrVdcm6IEB3dq4IWICUWuOuameK
https://drive.google.com/file/d/1CBcgT1GpANPWRkqXajyzSfmiJjGd8-yz/view

Fixed: 1474050
Change-Id: Ib7b2b84d6ba35d07a75a1b617fef862c3d9d7a76
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4827348
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
Reviewed-by: Marlon Facey <mfacey@chromium.org>
Commit-Queue: Roman Arora <romanarora@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1191458}
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.html b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.html
index 47cb2fa3..a021504 100644
--- a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.html
+++ b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.html
@@ -4,13 +4,10 @@
     border-radius: var(--ntp-module-item-border-radius);
     display: flex;
     flex-direction: column;
+    position: relative;
   }
 
-  :host([suggestion-chip-header-enabled_]) {
-    background: transparent;
-    border: none;
-  }
-
+  :host([suggestion-chip-header-enabled_]),
   :host([suggestion-chip-header-enabled_]) ntp-module-header-v2 {
     background: transparent;
     border: none;
@@ -24,26 +21,51 @@
     }
   }
 
-  #label-container {
+  .label-container {
     color: var(--color-new-tab-page-primary-foreground);
     display: flex;
     font-size: 20px;
     height: 48px;
     line-height: 24px;
+    margin-top: 8px;
     padding: 0 16px;
   }
 
-  :host([suggestion-chip-header-enabled_]) #label-container {
-    background: var(--color-new-tab-page-module-item-background);
-    border-radius: var(--ntp-module-item-border-radius);
-    height: 100%;
+  :host(:not([suggestion-chip-header-enabled_]):hover) {
+    cursor: pointer;
   }
 
-  :host([suggestion-chip-header-enabled_][format='wide']:not([show-related-searches])) #label-container {
-    align-items: start;
-    padding: 16px;
+  :host(:not([suggestion-chip-header-enabled_]):hover) .hover-layer,
+  #suggestion-chip:hover .hover-layer {
+    background: var(--color-new-tab-page-module-item-background-hovered);
+    display: block;
+    inset: 0;
+    position: absolute;
   }
 
+  .hover-layer {
+    border-radius: var(--ntp-module-item-border-radius);
+    display: none;
+    pointer-events: none;
+  }
+
+  :host([suggestion-chip-header-enabled_]) .label-container {
+    background: var(--color-new-tab-page-module-item-background);
+    border-radius: var(--ntp-module-item-border-radius);
+  }
+
+  :host([suggestion-chip-header-enabled_][format='wide']:not([show-related-searches]))
+      .label-container {
+    align-items: start;
+  }
+
+  :host([suggestion-chip-header-enabled_][format='wide']
+      :not([show-related-searches])) #suggestion-chip {
+    height: 116px;
+  }
+
+
+
   h2 {
     -webkit-line-clamp: 2;
     -webkit-box-orient: vertical;
@@ -62,13 +84,21 @@
   #suggestion-chip {
     display: flex;
     font-size: var(--ntp-module-text-size);
+    position: relative;
+    text-decoration: none;
+  }
+
+  #suggestion-chip:focus, #suggestion-chip:focus-visible {
+    box-shadow: var(--ntp-focus-shadow);
+    outline: none;
   }
 
   #suggestion-chip-icon {
     --cr-icon-ripple-size: 16px;
     --cr-icon-image: url(chrome://resources/images/icon_history.svg);
+    align-self: center;
     background-color: var(--color-new-tab-page-primary-foreground);
-    margin: auto;
+    margin: 16px 0;
   }
 
   #suggestion-chip-label {
@@ -77,6 +107,7 @@
     line-height: 20px;
   }
 </style>
+<div class="hover-layer" hidden="[[suggestionChipHeaderEnabled_]]"></div>
 <ntp-module-header-v2
     id="moduleHeaderElementV2"
     header-text="[[i18n('modulesJourneysResumeJourney', '')]]"
@@ -84,12 +115,13 @@
     menu-item-groups="[[getMenuItemGroups_()]]"
     more-actions-text="[[i18n('modulesMoreActions', clusterLabel)]]">
 </ntp-module-header-v2>
-<div id="label-container">
-  <h2 id="label" hidden="[[suggestionChipHeaderEnabled_]]">
-    [[clusterLabel]]
-  </h2>
-  <div id="suggestion-chip" hidden="[[!suggestionChipHeaderEnabled_]]">
-    <div id="suggestion-chip-icon" class="cr-icon"></div>
-    <h2 id="suggestion-chip-label">[[clusterLabel]]</h2>
-  </div>
-</div>
+<h2 id="label" class="label-container"
+    hidden="[[suggestionChipHeaderEnabled_]]">
+[[clusterLabel]]
+</h2>
+<a id="suggestion-chip" class="label-container" href="[[normalizedUrl.url]]"
+    hidden="[[!suggestionChipHeaderEnabled_]]" on-click="onSuggestClick_">
+  <div class="hover-layer"></div>
+  <div id="suggestion-chip-icon" class="cr-icon"></div>
+  <h2 id="suggestion-chip-label">[[clusterLabel]]</h2>
+</a>
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.ts b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.ts
index b810c23f..5997959 100644
--- a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.ts
+++ b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/header_tile.ts
@@ -8,6 +8,8 @@
 import 'chrome://resources/cr_elements/cr_shared_style.css.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 
+import {EventTracker} from 'chrome://resources/js/event_tracker.js';
+import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {I18nMixin, loadTimeData} from '../../../i18n_setup.js';
@@ -39,17 +41,51 @@
       /** Whether suggestion chip header will show. */
       suggestionChipHeaderEnabled_: {
         type: Boolean,
+        reflectToAttribute: true,
         value: () => loadTimeData.getBoolean(
             'historyClustersSuggestionChipHeaderEnabled'),
-        reflectToAttribute: true,
       },
     };
   }
 
-  clusterLabel: string;
-  private suggestionChipHeaderEnabled_: boolean;
+clusterId:
+  number;
+clusterLabel:
+  string;
+normalizedUrl:
+  Url;
+private suggestionChipHeaderEnabled_:
+  boolean;
+private eventTracker_:
+  EventTracker = new EventTracker();
+
+  override connectedCallback() {
+    super.connectedCallback();
+
+    if (!this.suggestionChipHeaderEnabled_) {
+      this.eventTracker_.add(this, 'click', this.onClick_);
+    }
+  }
+
+  override disconnectedCallback() {
+    super.disconnectedCallback();
+    this.eventTracker_.removeAll();
+  }
+
+  private onClick_(e: Event) {
+    e.stopPropagation();
+    this.dispatchEvent(new CustomEvent(
+        'show-all-button-click', {bubbles: true, composed: true}));
+  }
+
+  private onSuggestClick_(e: Event) {
+    e.stopPropagation();
+    this.dispatchEvent(
+        new CustomEvent('suggest-click', {bubbles: true, composed: true}));
+  }
 
   private onMenuButtonClick_(e: Event) {
+    e.stopPropagation();
     this.$.moduleHeaderElementV2.showAt(e);
   }
 
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/module.html b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/module.html
index b993771..4f6a221c 100644
--- a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/module.html
+++ b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/module.html
@@ -141,7 +141,9 @@
       on-done-button-click="onDoneButtonClick_"
       on-info-button-click="onInfoButtonClick_"
       on-show-all-button-click="onShowAllButtonClick_"
+      on-suggest-click="onSuggestClick_"
       cluster-label="[[computeLabel_()]]"
+      normalized-url="[[cluster.visits.0.normalizedUrl]]"
       format$="[[format]]"
       show-related-searches$="[[showRelatedSearches]]">
   </history-clusters-header-v2>
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/module.ts b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/module.ts
index 19900004..08cbb548 100644
--- a/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/module.ts
+++ b/chrome/browser/resources/new_tab_page/modules/v2/history_clusters/module.ts
@@ -71,7 +71,7 @@
 
       showRelatedSearches: {
         type: Boolean,
-        computed: `computeShowRelatedSearches()`,
+        computed: `computeShowRelatedSearches(cluster)`,
         reflectToAttribute: true,
       },
     };
@@ -176,10 +176,16 @@
     this.$.infoDialogRender.get().showModal();
   }
 
+  private onSuggestClick_() {
+    HistoryClustersProxyImpl.getInstance().handler.recordClick(this.cluster.id);
+    this.dispatchEvent(new Event('usage', {bubbles: true, composed: true}));
+  }
+
   private onShowAllButtonClick_() {
-    assert(this.cluster.label.length >= 2);
+    assert(this.cluster.label.length >= 2, 'Unexpected cluster label length');
     HistoryClustersProxyImpl.getInstance().handler.showJourneysSidePanel(
         this.cluster.label.substring(1, this.cluster.label.length - 1));
+    this.dispatchEvent(new Event('usage', {bubbles: true, composed: true}));
   }
 
   private shouldShowCartTile_(cart: Object): boolean {
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/module_header.ts b/chrome/browser/resources/new_tab_page/modules/v2/module_header.ts
index e190d329..4c97751 100644
--- a/chrome/browser/resources/new_tab_page/modules/v2/module_header.ts
+++ b/chrome/browser/resources/new_tab_page/modules/v2/module_header.ts
@@ -68,7 +68,8 @@
     }
   }
 
-  private onMenuButtonClick_() {
+  private onMenuButtonClick_(e: Event) {
+    e.stopPropagation();
     this.dispatchEvent(new Event('menu-button-click', {bubbles: true}));
   }
 
diff --git a/chrome/test/data/webui/new_tab_page/modules/v2/history_clusters/module_test.ts b/chrome/test/data/webui/new_tab_page/modules/v2/history_clusters/module_test.ts
index bea2c5c..f678191 100644
--- a/chrome/test/data/webui/new_tab_page/modules/v2/history_clusters/module_test.ts
+++ b/chrome/test/data/webui/new_tab_page/modules/v2/history_clusters/module_test.ts
@@ -41,6 +41,11 @@
   return cluster;
 }
 
+function removeHrefAndClick(element: HTMLElement) {
+  element.removeAttribute('href');
+  element.click();
+}
+
 suite('NewTabPageModulesHistoryClustersV2ModuleTest', () => {
   let handler: TestMock<PageHandlerRemote>;
 
@@ -131,8 +136,32 @@
       assertTrue(!!$$(moduleElement, 'ntp-info-dialog'));
     });
 
-    test('Header contains label that is not hidden', async () => {
-      // Arrange.
+    test(
+        'Search suggestion header contains chip that is not hidden',
+        async () => {
+          // Arrange.
+          loadTimeData.overrideValues({
+            historyClustersSuggestionChipHeaderEnabled: true,
+          });
+          const moduleElements = await initializeModule(
+              [createSampleCluster(2, {label: '"Sample Journey"'})]);
+          const moduleElement = moduleElements[0];
+
+          // Act.
+          assertTrue(!!moduleElement);
+          const headerElement = $$(moduleElement, 'history-clusters-header-v2');
+          assertTrue(!!headerElement);
+          const label = $$(headerElement, '#label');
+          assertTrue(!!label);
+          const suggestionChip = $$(headerElement, '#suggestion-chip');
+          assertTrue(!!suggestionChip);
+
+          // Assert.
+          assertEquals((label as HTMLElement).hidden, true);
+          assertEquals((suggestionChip as HTMLElement).hidden, false);
+        });
+
+    test('Search suggestion header click triggers navigation', async () => {
       loadTimeData.overrideValues({
         historyClustersSuggestionChipHeaderEnabled: true,
       });
@@ -144,14 +173,12 @@
       assertTrue(!!moduleElement);
       const headerElement = $$(moduleElement, 'history-clusters-header-v2');
       assertTrue(!!headerElement);
-      const label = $$(headerElement, '#label');
-      assertTrue(!!label);
-      const suggestionChip = $$(headerElement, '#suggestion-chip');
+      const suggestionChip = $$<HTMLElement>(headerElement, '#suggestion-chip');
       assertTrue(!!suggestionChip);
 
-      // Assert.
-      assertEquals((label as HTMLElement).hidden, true);
-      assertEquals((suggestionChip as HTMLElement).hidden, false);
+      const waitForUsageEvent = eventToPromise('usage', moduleElement);
+      removeHrefAndClick(suggestionChip);
+      await waitForUsageEvent;
     });
 
     test(
@@ -230,22 +257,46 @@
               InteractionState.kDefault, 3);
         });
 
+    test('Show History side panel invoked when clicking header', async () => {
+      loadTimeData.overrideValues({
+        historyClustersSuggestionChipHeaderEnabled: false,
+      });
+
+      const sampleClusterLabel = '"Sample Journey"';
+      const moduleElements = await initializeModule(
+          [createSampleCluster(2, {label: sampleClusterLabel})]);
+      const moduleElement = moduleElements[0];
+      assertTrue(!!moduleElement);
+      const headerElement = $$(moduleElement, 'history-clusters-header-v2');
+      assertTrue(!!headerElement);
+
+      const waitForUsageEvent = eventToPromise('usage', moduleElement);
+      headerElement.click();
+
+      assertEquals(
+          sampleClusterLabel.substring(1, sampleClusterLabel.length - 1),
+          handler.getArgs('showJourneysSidePanel')[0]);
+      await waitForUsageEvent;
+    });
+
     test(
-        'Show Journeys side panel is invoked when performing show all action',
+        'Show History side panel is invoked when performing show all action',
         async () => {
           const sampleClusterLabel = '"Sample Journey"';
           const moduleElements = await initializeModule(
               [createSampleCluster(2, {label: sampleClusterLabel})]);
           const moduleElement = moduleElements[0];
           assertTrue(!!moduleElement);
-
           const headerElement = $$(moduleElement, 'history-clusters-header-v2');
           assertTrue(!!headerElement);
+
+          const waitForUsageEvent = eventToPromise('usage', moduleElement);
           headerElement!.dispatchEvent(new Event('show-all-button-click'));
 
           assertEquals(
               sampleClusterLabel.substring(1, sampleClusterLabel.length - 1),
               handler.getArgs('showJourneysSidePanel')[0]);
+          await waitForUsageEvent;
         });
 
     [...Array(3).keys()].forEach(numRelatedSearches => {