diff --git a/static_src/elements/framework/mr-issue-list/mr-show-columns-dropdown.js b/static_src/elements/framework/mr-issue-list/mr-show-columns-dropdown.js
new file mode 100644
index 0000000..5d6a97b
--- /dev/null
+++ b/static_src/elements/framework/mr-issue-list/mr-show-columns-dropdown.js
@@ -0,0 +1,310 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+import {css} from 'lit-element';
+import {MrDropdown} from 'elements/framework/mr-dropdown/mr-dropdown.js';
+import page from 'page';
+import qs from 'qs';
+import {connectStore} from 'reducers/base.js';
+import * as projectV0 from 'reducers/projectV0.js';
+import * as sitewide from 'reducers/sitewide.js';
+import {fieldTypes, fieldsForIssue} from 'shared/issue-fields.js';
+
+
+/**
+ * `<mr-show-columns-dropdown>`
+ *
+ * Issue list column options dropdown.
+ *
+ */
+export class MrShowColumnsDropdown extends connectStore(MrDropdown) {
+  /** @override */
+  static get styles() {
+    return [
+      ...MrDropdown.styles,
+      css`
+        :host {
+          font-weight: normal;
+          color: var(--chops-link-color);
+          --mr-dropdown-icon-color: var(--chops-link-color);
+          --mr-dropdown-anchor-padding: 3px 8px;
+          --mr-dropdown-anchor-font-weight: bold;
+          --mr-dropdown-menu-min-width: 150px;
+          --mr-dropdown-menu-font-size: var(--chops-main-font-size);
+          --mr-dropdown-menu-icon-size: var(--chops-main-font-size);
+          /* Because we're using a sticky header, we need to make sure the
+           * dropdown cannot be taller than the screen. */
+          --mr-dropdown-menu-max-height: 80vh;
+          --mr-dropdown-menu-overflow: auto;
+        }
+      `,
+    ];
+  }
+  /** @override */
+  static get properties() {
+    return {
+      ...MrDropdown.properties,
+      /**
+       * Array of displayed columns.
+       */
+      columns: {type: Array},
+      /**
+       * Array of displayed issues.
+       */
+      issues: {type: Array},
+      /**
+       * Array of unique phase names to prepend to phase field columns.
+       */
+      // TODO(dtu): Delete after removing EZT hotlist issue list.
+      phaseNames: {type: Array},
+      /**
+       * Array of built in fields that are available outside of project
+       * configuration.
+       */
+      defaultFields: {type: Array},
+      _fieldDefs: {type: Array},
+      _labelPrefixFields: {type: Array},
+      // TODO(zhangtiff): Delete this legacy integration after removing
+      // the EZT issue list view.
+      onHideColumn: {type: Object},
+      onShowColumn: {type: Object},
+    };
+  }
+
+  /** @override */
+  constructor() {
+    super();
+
+    // Inherited from MrDropdown.
+    this.label = 'Show columns';
+    this.icon = 'more_horiz';
+
+    this.columns = [];
+    /** @type {Array<Issue>} */
+    this.issues = [];
+    this.phaseNames = [];
+    this.defaultFields = [];
+
+    // TODO(dtu): Delete after removing EZT hotlist issue list.
+    this._fieldDefs = [];
+    this._labelPrefixFields = [];
+
+    this._queryParams = {};
+    this._page = page;
+
+    // TODO(zhangtiff): Delete this legacy integration after removing
+    // the EZT issue list view.
+    this.onHideColumn = null;
+    this.onShowColumn = null;
+  }
+
+  /** @override */
+  stateChanged(state) {
+    this._fieldDefs = projectV0.fieldDefs(state) || [];
+    this._labelPrefixFields = projectV0.labelPrefixFields(state) || [];
+    this._queryParams = sitewide.queryParams(state);
+  }
+
+  /** @override */
+  update(changedProperties) {
+    if (this.issues.length) {
+      this.items = this.columnOptions();
+    } else {
+      // TODO(dtu): Delete after removing EZT hotlist issue list.
+      this.items = this.columnOptionsEzt(
+          this.defaultFields, this._fieldDefs, this._labelPrefixFields,
+          this.columns, this.phaseNames);
+    }
+
+    super.update(changedProperties);
+  }
+
+  /**
+   * Computes the column options available in the list view based on Issues.
+   * @return {Array<MenuItem>}
+   */
+  columnOptions() {
+    const availableFields = new Set(this.defaultFields);
+    this.issues.forEach((issue) => {
+      fieldsForIssue(issue).forEach((field) => {
+        availableFields.add(field);
+      });
+    });
+
+    // Remove selected columns from available fields.
+    this.columns.forEach((field) => availableFields.delete(field));
+    const sortedFields = [...availableFields].sort();
+
+    return [
+      // Show selected options first.
+      ...this.columns.map((field, i) => ({
+        icon: 'check',
+        text: field,
+        handler: () => this._removeColumn(i),
+      })),
+      // Unselected options come next.
+      ...sortedFields.map((field) => ({
+        icon: '',
+        text: field,
+        handler: () => this._addColumn(field),
+      })),
+    ];
+  }
+
+  // TODO(dtu): Delete after removing EZT hotlist issue list.
+  /**
+   * Computes the column options available in the list view based on project
+   * config data.
+   * @param {Array<string>} defaultFields List of built in columns.
+   * @param {Array<FieldDef>} fieldDefs List of custom fields configured in the
+   *   viewed project.
+   * @param {Array<string>} labelPrefixes List of available label prefixes for
+   *   the current project config..
+   * @param {Array<string>} selectedColumns List of columns the user is
+   *   currently viewing.
+   * @param {Array<string>} phaseNames All phase namws present in the currently
+   *   viewed issue list.
+   * @return {Array<MenuItem>}
+   */
+  columnOptionsEzt(defaultFields, fieldDefs, labelPrefixes, selectedColumns,
+      phaseNames) {
+    const selectedOptions = new Set(
+        selectedColumns.map((col) => col.toLowerCase()));
+
+    const availableFields = new Set();
+
+    // Built-in, hard-coded fields like Owner, Status, and Labels.
+    defaultFields.forEach((field) => this._addUnselectedField(
+        availableFields, field, selectedOptions));
+
+    // Custom fields.
+    fieldDefs.forEach((fd) => {
+      const {fieldRef, isPhaseField} = fd;
+      const {fieldName, type} = fieldRef;
+      if (isPhaseField) {
+        // If the custom field belongs to phases, prefix the phase name for
+        // each phase.
+        phaseNames.forEach((phaseName) => {
+          this._addUnselectedField(
+              availableFields, `${phaseName}.${fieldName}`, selectedOptions);
+        });
+        return;
+      }
+
+      // TODO(zhangtiff): Prefix custom fields with "approvalName" defined by
+      // the approval name after deprecating the old issue list page.
+
+      // Most custom fields can be directly added to the list with no
+      // modifications.
+      this._addUnselectedField(
+          availableFields, fieldName, selectedOptions);
+
+      // If the custom field is type approval, then it also has a built in
+      // "Approver" field.
+      if (type === fieldTypes.APPROVAL_TYPE) {
+        this._addUnselectedField(
+            availableFields, `${fieldName}-Approver`, selectedOptions);
+      }
+    });
+
+    // Fields inferred from label prefixes.
+    labelPrefixes.forEach((field) => this._addUnselectedField(
+        availableFields, field, selectedOptions));
+
+    const sortedFields = [...availableFields];
+    sortedFields.sort();
+
+    return [
+      ...selectedColumns.map((field, i) => ({
+        icon: 'check',
+        text: field,
+        handler: () => this._removeColumn(i),
+      })),
+      ...sortedFields.map((field) => ({
+        icon: '',
+        text: field,
+        handler: () => this._addColumn(field),
+      })),
+    ];
+  }
+
+  /**
+   * Helper that mutates a Set of column names in place, adding a given
+   * field only if it doesn't already show up in the list of selected
+   * fields.
+   * @param {Set<string>} availableFields Set of column names to mutate.
+   * @param {string} field Name of the field being added to the options.
+   * @param {Set<string>} selectedOptions Set of fieldNames that the user
+   *   is viewing.
+   * @private
+   */
+  _addUnselectedField(availableFields, field, selectedOptions) {
+    if (!selectedOptions.has(field.toLowerCase())) {
+      availableFields.add(field);
+    }
+  }
+
+  /**
+   * Removes the column at a particular index.
+   *
+   * @param {number} i the issue column to be removed.
+   */
+  _removeColumn(i) {
+    if (this.onHideColumn) {
+      if (!this.onHideColumn(this.columns[i])) {
+        return;
+      }
+    }
+    const columns = [...this.columns];
+    columns.splice(i, 1);
+    this._reloadColspec(columns);
+  }
+
+  /**
+   * Adds a new column to a particular index.
+   *
+   * @param {string} name of the new column added.
+   */
+  _addColumn(name) {
+    if (this.onShowColumn) {
+      if (!this.onShowColumn(name)) {
+        return;
+      }
+    }
+    this._reloadColspec([...this.columns, name]);
+  }
+
+  /**
+   * Reflects changes to the columns of an issue list to the URL, through
+   * frontend routing.
+   *
+   * @param {Array} newColumns the new colspec to set in the URL.
+   */
+  _reloadColspec(newColumns) {
+    this._updateQueryParams({colspec: newColumns.join(' ')});
+  }
+
+  /**
+   * Navigates to the same URL as the current page, but with query
+   * params updated.
+   *
+   * @param {Object} newParams keys and values of the queryParams
+   * Object to be updated.
+   */
+  _updateQueryParams(newParams) {
+    const params = {...this._queryParams, ...newParams};
+    this._page(`${this._baseUrl()}?${qs.stringify(params)}`);
+  }
+
+  /**
+   * Get the current URL of the page, without query params. Useful for
+   * test stubbing.
+   *
+   * @return {string} the URL of the list page, without params.
+   */
+  _baseUrl() {
+    return window.location.pathname;
+  }
+}
+
+customElements.define('mr-show-columns-dropdown', MrShowColumnsDropdown);
