You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by kg...@apache.org on 2021/05/05 13:38:00 UTC

[superset] branch master updated: chore: Move styles from .less stylesheet to emotion in Explore (#14485)

This is an automated email from the ASF dual-hosted git repository.

kgabryje pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new b030c98  chore: Move styles from .less stylesheet to emotion in Explore (#14485)
b030c98 is described below

commit b030c9801cd500f86368608a28b5a937b03f3297
Author: Kamil Gabryjelski <ka...@gmail.com>
AuthorDate: Wed May 5 15:36:52 2021 +0200

    chore: Move styles from .less stylesheet to emotion in Explore (#14485)
    
    * Move some styles from .less stylesheet to emotion in Explore
    
    * Replace Global styles with local styled components
    
    * Address comments
---
 .../components/AdhocMetricStaticOption_spec.jsx    | 42 -----------
 .../components/FilterDefinitionOption_spec.jsx     | 17 ++---
 .../components/MetricDefinitionOption_spec.jsx     | 13 ++--
 .../FiltersConfigForm/FiltersConfigForm.tsx        |  2 -
 .../FiltersConfigModal/FiltersConfigForm/main.less | 86 ----------------------
 .../explore/components/DatasourcePanel/index.tsx   | 16 ++--
 ...cStaticOption.jsx => ExploreContentPopover.tsx} | 41 +++++------
 .../DndColumnSelectControl/DndColumnSelect.tsx     |  5 +-
 .../FilterControl/AdhocFilterEditPopover/index.jsx | 36 ++++++++-
 .../AdhocFilterEditPopoverSqlTabContent/index.jsx  |  2 +-
 .../AdhocFilterPopoverTrigger/index.tsx            | 21 +++---
 .../MetricControl/AdhocMetricEditPopover/index.jsx | 29 +++-----
 .../MetricControl/AdhocMetricPopoverTrigger.tsx    | 29 ++++----
 .../MetricControl/FilterDefinitionOption.jsx       | 20 +++--
 .../MetricControl/MetricDefinitionOption.jsx       |  9 ++-
 .../components/controls/OptionControls/index.tsx   |  8 +-
 .../src/explore/components/optionRenderers.tsx     | 55 ++++++++++++++
 superset-frontend/src/explore/controls.jsx         | 10 +--
 superset-frontend/src/explore/main.less            | 67 -----------------
 19 files changed, 197 insertions(+), 311 deletions(-)

diff --git a/superset-frontend/spec/javascripts/explore/components/AdhocMetricStaticOption_spec.jsx b/superset-frontend/spec/javascripts/explore/components/AdhocMetricStaticOption_spec.jsx
deleted file mode 100644
index cba7178..0000000
--- a/superset-frontend/spec/javascripts/explore/components/AdhocMetricStaticOption_spec.jsx
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/* eslint-disable no-unused-expressions */
-import React from 'react';
-import { shallow } from 'enzyme';
-
-import { AGGREGATES } from 'src/explore/constants';
-import AdhocMetricStaticOption from 'src/explore/components/controls/MetricControl/AdhocMetricStaticOption';
-import AdhocMetric, {
-  EXPRESSION_TYPES,
-} from 'src/explore/components/controls/MetricControl/AdhocMetric';
-
-const sumValueAdhocMetric = new AdhocMetric({
-  expressionType: EXPRESSION_TYPES.SIMPLE,
-  column: { type: 'VARCHAR(255)', column_name: 'source' },
-  aggregate: AGGREGATES.SUM,
-});
-
-describe('AdhocMetricStaticOption', () => {
-  it('renders the adhoc metrics label', () => {
-    const wrapper = shallow(
-      <AdhocMetricStaticOption adhocMetric={sumValueAdhocMetric} />,
-    );
-    expect(wrapper.text()).toBe('SUM(source)');
-  });
-});
diff --git a/superset-frontend/spec/javascripts/explore/components/FilterDefinitionOption_spec.jsx b/superset-frontend/spec/javascripts/explore/components/FilterDefinitionOption_spec.jsx
index f12212f..0e36348 100644
--- a/superset-frontend/spec/javascripts/explore/components/FilterDefinitionOption_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/FilterDefinitionOption_spec.jsx
@@ -19,14 +19,13 @@
 /* eslint-disable no-unused-expressions */
 import React from 'react';
 import { shallow } from 'enzyme';
-
-import { ColumnOption } from '@superset-ui/chart-controls';
+import { styledMount as mount } from 'spec/helpers/theming';
 import FilterDefinitionOption from 'src/explore/components/controls/MetricControl/FilterDefinitionOption';
-import AdhocMetricStaticOption from 'src/explore/components/controls/MetricControl/AdhocMetricStaticOption';
 import { AGGREGATES } from 'src/explore/constants';
 import AdhocMetric, {
   EXPRESSION_TYPES,
 } from 'src/explore/components/controls/MetricControl/AdhocMetric';
+import { StyledColumnOption } from 'src/explore/components/optionRenderers';
 
 const sumValueAdhocMetric = new AdhocMetric({
   expressionType: EXPRESSION_TYPES.SIMPLE,
@@ -35,26 +34,26 @@ const sumValueAdhocMetric = new AdhocMetric({
 });
 
 describe('FilterDefinitionOption', () => {
-  it('renders a ColumnOption given a column', () => {
+  it('renders a StyledColumnOption given a column', () => {
     const wrapper = shallow(
       <FilterDefinitionOption option={{ column_name: 'a_column' }} />,
     );
-    expect(wrapper.find(ColumnOption)).toExist();
+    expect(wrapper.find(StyledColumnOption)).toExist();
   });
 
-  it('renders a AdhocMetricStaticOption given an adhoc metric', () => {
+  it('renders a StyledColumnOption given an adhoc metric', () => {
     const wrapper = shallow(
       <FilterDefinitionOption option={sumValueAdhocMetric} />,
     );
-    expect(wrapper.find(AdhocMetricStaticOption)).toExist();
+    expect(wrapper.find(StyledColumnOption)).toExist();
   });
 
   it('renders the metric name given a saved metric', () => {
-    const wrapper = shallow(
+    const wrapper = mount(
       <FilterDefinitionOption
         option={{ saved_metric_name: 'my_custom_metric' }}
       />,
     );
-    expect(wrapper.text()).toBe('<ColumnTypeLabel />my_custom_metric');
+    expect(wrapper.find('.option-label').text()).toBe('my_custom_metric');
   });
 });
diff --git a/superset-frontend/spec/javascripts/explore/components/MetricDefinitionOption_spec.jsx b/superset-frontend/spec/javascripts/explore/components/MetricDefinitionOption_spec.jsx
index dda794b..7ab2bdc 100644
--- a/superset-frontend/spec/javascripts/explore/components/MetricDefinitionOption_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/MetricDefinitionOption_spec.jsx
@@ -19,10 +19,13 @@
 import React from 'react';
 import configureStore from 'redux-mock-store';
 import { shallow } from 'enzyme';
-import { ColumnOption, MetricOption } from '@superset-ui/chart-controls';
 
 import MetricDefinitionOption from 'src/explore/components/controls/MetricControl/MetricDefinitionOption';
 import AggregateOption from 'src/explore/components/controls/MetricControl/AggregateOption';
+import {
+  StyledMetricOption,
+  StyledColumnOption,
+} from 'src/explore/components/optionRenderers';
 
 describe('MetricDefinitionOption', () => {
   const mockStore = configureStore([]);
@@ -32,16 +35,16 @@ describe('MetricDefinitionOption', () => {
     return shallow(<MetricDefinitionOption store={store} {...props} />).dive();
   }
 
-  it('renders a MetricOption given a saved metric', () => {
+  it('renders a StyledMetricOption given a saved metric', () => {
     const wrapper = setup({
       option: { metric_name: 'a_saved_metric', expression: 'COUNT(*)' },
     });
-    expect(wrapper.find(MetricOption)).toExist();
+    expect(wrapper.find(StyledMetricOption)).toExist();
   });
 
-  it('renders a ColumnOption given a column', () => {
+  it('renders a StyledColumnOption given a column', () => {
     const wrapper = setup({ option: { column_name: 'a_column' } });
-    expect(wrapper.find(ColumnOption)).toExist();
+    expect(wrapper.find(StyledColumnOption)).toExist();
   });
 
   it('renders an AggregateOption given an aggregate metric', () => {
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
index 182e1e0..d3c3298 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
@@ -66,8 +66,6 @@ import {
   CASCADING_FILTERS,
   getFiltersConfigModalTestId,
 } from '../FiltersConfigModal';
-// TODO: move styles from AdhocFilterControl to emotion and delete this ./main.less
-import './main.less';
 
 const StyledContainer = styled.div`
   display: flex;
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/main.less b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/main.less
deleted file mode 100644
index d530ea0..0000000
--- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/main.less
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-@import '../../../../../../stylesheets/less/variables.less';
-
-.option-label {
-  display: inline-block;
-  & ~ i {
-    margin-left: 4px;
-  }
-}
-
-.type-label {
-  margin-right: 8px;
-  width: 30px;
-  display: inline-block;
-  text-align: center;
-  font-weight: @font-weight-bold;
-}
-
-.adhoc-filter-edit-tabs > .nav-tabs {
-  margin-bottom: 8px;
-
-  & > li > a {
-    padding: 4px;
-  }
-}
-
-.edit-popover-resize {
-  transform: scaleX(-1);
-  -moz-transform: scaleX(-1);
-  -webkit-transform: scaleX(-1);
-  -ms-transform: scaleX(-1);
-  float: right;
-  margin-top: 18px;
-  margin-right: -10px;
-  cursor: nwse-resize;
-}
-
-#filter-edit-popover {
-  max-width: none;
-}
-
-.filter-edit-clause-dropdown {
-  width: 120px;
-  margin-right: 5px;
-}
-
-.filter-edit-clause-info {
-  font-size: @font-size-xs;
-  padding-left: 5px;
-}
-
-.filter-edit-clause-section {
-  display: inline-flex;
-}
-
-.adhoc-filter-sql-editor {
-  border: @gray-light solid thin;
-}
-
-.adhoc-filter-simple-column-dropdown {
-  margin-top: 20px;
-}
-
-.custom-sql-disabled-message {
-  color: @gray;
-  font-size: @font-size-xs;
-  text-align: center;
-  margin-top: 60px;
-}
diff --git a/superset-frontend/src/explore/components/DatasourcePanel/index.tsx b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx
index 40063c2..bac9bab 100644
--- a/superset-frontend/src/explore/components/DatasourcePanel/index.tsx
+++ b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx
@@ -19,12 +19,7 @@
 import React, { useEffect, useState } from 'react';
 import { styled, t } from '@superset-ui/core';
 import Collapse from 'src/components/Collapse';
-import {
-  ColumnOption,
-  MetricOption,
-  ControlConfig,
-  DatasourceMeta,
-} from '@superset-ui/chart-controls';
+import { ControlConfig, DatasourceMeta } from '@superset-ui/chart-controls';
 import { debounce } from 'lodash';
 import { matchSorter, rankings } from 'match-sorter';
 import { FAST_DEBOUNCE } from 'src/constants';
@@ -33,6 +28,7 @@ import { ExploreActions } from 'src/explore/actions/exploreActions';
 import Control from 'src/explore/components/Control';
 import DatasourcePanelDragWrapper from './DatasourcePanelDragWrapper';
 import { DndItemType } from '../DndItemType';
+import { StyledColumnOption, StyledMetricOption } from '../optionRenderers';
 
 interface DatasourceControl extends ControlConfig {
   datasource?: DatasourceMeta;
@@ -216,10 +212,10 @@ export default function DataSourcePanel({
                     value={m}
                     type={DndItemType.Metric}
                   >
-                    <MetricOption metric={m} showType />
+                    <StyledMetricOption metric={m} showType />
                   </DatasourcePanelDragWrapper>
                 ) : (
-                  <MetricOption metric={m} showType />
+                  <StyledMetricOption metric={m} showType />
                 )}
               </LabelContainer>
             ))}
@@ -238,10 +234,10 @@ export default function DataSourcePanel({
                     value={col}
                     type={DndItemType.Column}
                   >
-                    <ColumnOption column={col} showType />
+                    <StyledColumnOption column={col} showType />
                   </DatasourcePanelDragWrapper>
                 ) : (
-                  <ColumnOption column={col} showType />
+                  <StyledColumnOption column={col} showType />
                 )}
               </LabelContainer>
             ))}
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricStaticOption.jsx b/superset-frontend/src/explore/components/ExploreContentPopover.tsx
similarity index 55%
rename from superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricStaticOption.jsx
rename to superset-frontend/src/explore/components/ExploreContentPopover.tsx
index ee5eed7..6a91c6b 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricStaticOption.jsx
+++ b/superset-frontend/src/explore/components/ExploreContentPopover.tsx
@@ -16,26 +16,23 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import React from 'react';
-import PropTypes from 'prop-types';
-import { ColumnTypeLabel } from '@superset-ui/chart-controls';
+import { styled } from '@superset-ui/core';
 
-import adhocMetricType from './adhocMetricType';
-
-const propTypes = {
-  adhocMetric: adhocMetricType,
-  showType: PropTypes.bool,
-};
-
-export default function AdhocMetricStaticOption({
-  adhocMetric,
-  showType = false,
-}) {
-  return (
-    <div>
-      {showType && <ColumnTypeLabel type="expression" />}
-      <span className="option-label">{adhocMetric.label}</span>
-    </div>
-  );
-}
-AdhocMetricStaticOption.propTypes = propTypes;
+export const ExplorePopoverContent = styled.div`
+  .edit-popover-resize {
+    transform: scaleX(-1);
+    float: right;
+    margin-top: ${({ theme }) => theme.gridUnit * 4}px;
+    margin-right: ${({ theme }) => theme.gridUnit * -2}px;
+    cursor: nwse-resize;
+  }
+  .filter-sql-editor {
+    border: ${({ theme }) => theme.colors.grayscale.light2} solid thin;
+  }
+  .custom-sql-disabled-message {
+    color: ${({ theme }) => theme.colors.grayscale.light1};
+    font-size: ${({ theme }) => theme.typography.sizes.xs}px;
+    text-align: center;
+    margin-top: ${({ theme }) => theme.gridUnit * 15}px;
+  }
+`;
diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx
index 8a680bd..b6d6a28 100644
--- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx
+++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx
@@ -17,7 +17,7 @@
  * under the License.
  */
 import React, { useState } from 'react';
-import { ColumnMeta, ColumnOption } from '@superset-ui/chart-controls';
+import { ColumnMeta } from '@superset-ui/chart-controls';
 import { isEmpty } from 'lodash';
 import { LabelProps } from 'src/explore/components/controls/DndColumnSelectControl/types';
 import DndSelectLabel from 'src/explore/components/controls/DndColumnSelectControl/DndSelectLabel';
@@ -25,6 +25,7 @@ import OptionWrapper from 'src/explore/components/controls/DndColumnSelectContro
 import { OptionSelector } from 'src/explore/components/controls/DndColumnSelectControl/utils';
 import { DatasourcePanelDndItem } from 'src/explore/components/DatasourcePanel/types';
 import { DndItemType } from 'src/explore/components/DndItemType';
+import { StyledColumnOption } from 'src/explore/components/optionRenderers';
 
 export const DndColumnSelect = (props: LabelProps) => {
   const { value, options } = props;
@@ -66,7 +67,7 @@ export const DndColumnSelect = (props: LabelProps) => {
         onShiftOptions={onShiftOptions}
         type={DndItemType.ColumnOption}
       >
-        <ColumnOption column={column} showType />
+        <StyledColumnOption column={column} showType />
       </OptionWrapper>
     ));
 
diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopover/index.jsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopover/index.jsx
index f7ec6be..ba4a636 100644
--- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopover/index.jsx
+++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopover/index.jsx
@@ -55,6 +55,38 @@ const ResizeIcon = styled.i`
 const startingWidth = 320;
 const startingHeight = 240;
 
+const FilterPopoverContentContainer = styled.div`
+  .adhoc-filter-edit-tabs > .nav-tabs {
+    margin-bottom: ${({ theme }) => theme.gridUnit * 2}px;
+
+    & > li > a {
+      padding: ${({ theme }) => theme.gridUnit}px;
+    }
+  }
+
+  #filter-edit-popover {
+    max-width: none;
+  }
+
+  .filter-edit-clause-dropdown {
+    width: ${({ theme }) => theme.gridUnit * 30}px;
+    margin-right: ${({ theme }) => theme.gridUnit}px;
+  }
+
+  .filter-edit-clause-info {
+    font-size: ${({ theme }) => theme.typography.sizes.xs}px;
+    padding-left: ${({ theme }) => theme.gridUnit}px;
+  }
+
+  .filter-edit-clause-section {
+    display: inline-flex;
+  }
+
+  .adhoc-filter-simple-column-dropdown {
+    margin-top: ${({ theme }) => theme.gridUnit * 5}px;
+  }
+`;
+
 export default class AdhocFilterEditPopover extends React.Component {
   constructor(props) {
     super(props);
@@ -149,7 +181,7 @@ export default class AdhocFilterEditPopover extends React.Component {
     const hasUnsavedChanges = !adhocFilter.equals(propsAdhocFilter);
 
     return (
-      <div
+      <FilterPopoverContentContainer
         id="filter-edit-popover"
         {...popoverProps}
         data-test="filter-edit-popover"
@@ -229,7 +261,7 @@ export default class AdhocFilterEditPopover extends React.Component {
             className="fa fa-expand edit-popover-resize text-muted"
           />
         </div>
-      </div>
+      </FilterPopoverContentContainer>
     );
   }
 }
diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/index.jsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/index.jsx
index 6599e85..405d692 100644
--- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/index.jsx
+++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/index.jsx
@@ -145,7 +145,7 @@ export default class AdhocFilterEditPopoverSqlTabContent extends React.Component
             value={adhocFilter.sqlExpression || adhocFilter.translateToSql()}
             editorProps={{ $blockScrolling: true }}
             enableLiveAutocompletion
-            className="adhoc-filter-sql-editor"
+            className="filter-sql-editor"
             wrapEnabled
           />
         </FormGroup>
diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterPopoverTrigger/index.tsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterPopoverTrigger/index.tsx
index 45fe11f..530c1bb 100644
--- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterPopoverTrigger/index.tsx
+++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterPopoverTrigger/index.tsx
@@ -21,6 +21,7 @@ import Popover from 'src/components/Popover';
 import { OptionSortType } from 'src/explore/types';
 import AdhocFilterEditPopover from 'src/explore/components/controls/FilterControl/AdhocFilterEditPopover';
 import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
+import { ExplorePopoverContent } from 'src/explore/components/ExploreContentPopover';
 
 interface AdhocFilterPopoverTriggerProps {
   adhocFilter: AdhocFilter;
@@ -82,15 +83,17 @@ class AdhocFilterPopoverTrigger extends React.PureComponent<
           closePopover: this.closePopover,
         };
     const overlayContent = (
-      <AdhocFilterEditPopover
-        adhocFilter={adhocFilter}
-        options={this.props.options}
-        datasource={this.props.datasource}
-        partitionColumn={this.props.partitionColumn}
-        onResize={this.onPopoverResize}
-        onClose={closePopover}
-        onChange={this.props.onFilterEdit}
-      />
+      <ExplorePopoverContent>
+        <AdhocFilterEditPopover
+          adhocFilter={adhocFilter}
+          options={this.props.options}
+          datasource={this.props.datasource}
+          partitionColumn={this.props.partitionColumn}
+          onResize={this.onPopoverResize}
+          onClose={closePopover}
+          onChange={this.props.onFilterEdit}
+        />
+      </ExplorePopoverContent>
     );
 
     return (
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.jsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.jsx
index fd62b81..ef8a07c 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.jsx
@@ -23,8 +23,7 @@ import { FormGroup } from 'react-bootstrap';
 import Tabs from 'src/components/Tabs';
 import Button from 'src/components/Button';
 import { NativeSelect as Select } from 'src/components/Select';
-import { styled, t } from '@superset-ui/core';
-import { ColumnOption, MetricOption } from '@superset-ui/chart-controls';
+import { t } from '@superset-ui/core';
 
 import FormLabel from 'src/components/FormLabel';
 import { SQLEditor } from 'src/components/AsyncAceEditor';
@@ -37,6 +36,10 @@ import savedMetricType from 'src/explore/components/controls/MetricControl/saved
 import AdhocMetric, {
   EXPRESSION_TYPES,
 } from 'src/explore/components/controls/MetricControl/AdhocMetric';
+import {
+  StyledMetricOption,
+  StyledColumnOption,
+} from 'src/explore/components/optionRenderers';
 
 const propTypes = {
   onChange: PropTypes.func.isRequired,
@@ -56,16 +59,6 @@ const defaultProps = {
   getCurrentTab: noOp,
 };
 
-const ResizeIcon = styled.i`
-  margin-left: ${({ theme }) => theme.gridUnit * 2}px;
-`;
-
-const ColumnOptionStyle = styled.span`
-  .option-label {
-    display: inline;
-  }
-`;
-
 export const SAVED_TAB_KEY = 'SAVED';
 
 const startingWidth = 320;
@@ -255,11 +248,7 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
     if (column.metric_name && !column.verbose_name) {
       column.verbose_name = column.metric_name;
     }
-    return (
-      <ColumnOptionStyle>
-        <ColumnOption column={column} showType />
-      </ColumnOptionStyle>
-    );
+    return <StyledColumnOption column={column} showType />;
   }
 
   render() {
@@ -369,7 +358,7 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
                       }
                       key={savedMetric.id}
                     >
-                      <MetricOption metric={savedMetric} showType />
+                      <StyledMetricOption metric={savedMetric} showType />
                     </Select.Option>
                   ))}
               </Select>
@@ -433,7 +422,7 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
                   }
                   editorProps={{ $blockScrolling: true }}
                   enableLiveAutocompletion
-                  className="adhoc-filter-sql-editor"
+                  className="filter-sql-editor"
                   wrapEnabled
                 />
               </FormGroup>
@@ -465,7 +454,7 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
           >
             {t('Save')}
           </Button>
-          <ResizeIcon
+          <i
             role="button"
             aria-label="Resize"
             tabIndex={0}
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx
index e1201c6..3a5e2fb 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx
@@ -20,6 +20,7 @@ import React, { ReactNode } from 'react';
 import { Metric } from '@superset-ui/core';
 import Popover from 'src/components/Popover';
 import AdhocMetricEditPopoverTitle from 'src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle';
+import { ExplorePopoverContent } from 'src/explore/components/ExploreContentPopover';
 import AdhocMetricEditPopover, {
   SAVED_TAB_KEY,
 } from './AdhocMetricEditPopover';
@@ -176,19 +177,21 @@ class AdhocMetricPopoverTrigger extends React.PureComponent<
         };
 
     const overlayContent = (
-      <AdhocMetricEditPopover
-        adhocMetric={adhocMetric}
-        title={title}
-        columns={columns}
-        savedMetricsOptions={savedMetricsOptions}
-        savedMetric={savedMetric}
-        datasourceType={datasourceType}
-        onResize={this.onPopoverResize}
-        onClose={closePopover}
-        onChange={this.onChange}
-        getCurrentTab={this.getCurrentTab}
-        getCurrentLabel={this.getCurrentLabel}
-      />
+      <ExplorePopoverContent>
+        <AdhocMetricEditPopover
+          adhocMetric={adhocMetric}
+          title={title}
+          columns={columns}
+          savedMetricsOptions={savedMetricsOptions}
+          savedMetric={savedMetric}
+          datasourceType={datasourceType}
+          onResize={this.onPopoverResize}
+          onClose={closePopover}
+          onChange={this.onChange}
+          getCurrentTab={this.getCurrentTab}
+          getCurrentLabel={this.getCurrentLabel}
+        />
+      </ExplorePopoverContent>
     );
 
     const popoverTitle = (
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/FilterDefinitionOption.jsx b/superset-frontend/src/explore/components/controls/MetricControl/FilterDefinitionOption.jsx
index 0c5093a..0491090 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/FilterDefinitionOption.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/FilterDefinitionOption.jsx
@@ -18,11 +18,10 @@
  */
 import React from 'react';
 import PropTypes from 'prop-types';
-import { ColumnOption, ColumnTypeLabel } from '@superset-ui/chart-controls';
 
 import columnType from './columnType';
-import AdhocMetricStaticOption from './AdhocMetricStaticOption';
 import adhocMetricType from './adhocMetricType';
+import { StyledColumnOption } from '../../optionRenderers';
 
 const propTypes = {
   option: PropTypes.oneOfType([
@@ -35,17 +34,22 @@ const propTypes = {
 export default function FilterDefinitionOption({ option }) {
   if (option.saved_metric_name) {
     return (
-      <div>
-        <ColumnTypeLabel type="expression" />
-        <span className="option-label">{option.saved_metric_name}</span>
-      </div>
+      <StyledColumnOption
+        column={{ column_name: option.saved_metric_name, type: 'expression' }}
+        showType
+      />
     );
   }
   if (option.column_name) {
-    return <ColumnOption column={option} showType />;
+    return <StyledColumnOption column={option} showType />;
   }
   if (option.label) {
-    return <AdhocMetricStaticOption adhocMetric={option} showType />;
+    return (
+      <StyledColumnOption
+        column={{ column_name: option.label, type: 'expression' }}
+        showType
+      />
+    );
   }
 }
 FilterDefinitionOption.propTypes = propTypes;
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionOption.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionOption.jsx
index 121d02a..b0acad2 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionOption.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionOption.jsx
@@ -18,9 +18,12 @@
  */
 import React from 'react';
 import PropTypes from 'prop-types';
-import { ColumnOption, MetricOption } from '@superset-ui/chart-controls';
 
 import withToasts from 'src/messageToasts/enhancers/withToasts';
+import {
+  StyledColumnOption,
+  StyledMetricOption,
+} from 'src/explore/components/optionRenderers';
 import AggregateOption from './AggregateOption';
 import columnType from './columnType';
 import aggregateOptionType from './aggregateOptionType';
@@ -37,10 +40,10 @@ const propTypes = {
 
 function MetricDefinitionOption({ option, addWarningToast }) {
   if (option.metric_name) {
-    return <MetricOption metric={option} showType />;
+    return <StyledMetricOption metric={option} showType />;
   }
   if (option.column_name) {
-    return <ColumnOption column={option} showType />;
+    return <StyledColumnOption column={option} showType />;
   }
   if (option.aggregate_name) {
     return <AggregateOption aggregate={option} showType />;
diff --git a/superset-frontend/src/explore/components/controls/OptionControls/index.tsx b/superset-frontend/src/explore/components/controls/OptionControls/index.tsx
index 03d399e..521bcc9 100644
--- a/superset-frontend/src/explore/components/controls/OptionControls/index.tsx
+++ b/superset-frontend/src/explore/components/controls/OptionControls/index.tsx
@@ -19,14 +19,12 @@
 import React, { useRef } from 'react';
 import { useDrag, useDrop, DropTargetMonitor } from 'react-dnd';
 import { styled, t, useTheme } from '@superset-ui/core';
-import {
-  MetricOption,
-  InfoTooltipWithTrigger,
-} from '@superset-ui/chart-controls';
+import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
 import { Tooltip } from 'src/components/Tooltip';
 import Icon from 'src/components/Icon';
 import { savedMetricType } from 'src/explore/components/controls/MetricControl/types';
 import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetric';
+import { StyledMetricOption } from '../../optionRenderers';
 
 export const DragContainer = styled.div`
   margin-bottom: ${({ theme }) => theme.gridUnit}px;
@@ -246,7 +244,7 @@ export const OptionControlLabel = ({
 
   const getLabelContent = () => {
     if (savedMetric?.metric_name) {
-      return <MetricOption metric={savedMetric} />;
+      return <StyledMetricOption metric={savedMetric} />;
     }
     return <Tooltip title={label}>{label}</Tooltip>;
   };
diff --git a/superset-frontend/src/explore/components/optionRenderers.tsx b/superset-frontend/src/explore/components/optionRenderers.tsx
new file mode 100644
index 0000000..368138a
--- /dev/null
+++ b/superset-frontend/src/explore/components/optionRenderers.tsx
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from 'react';
+import { styled } from '@superset-ui/core';
+import {
+  MetricOption,
+  ColumnOption,
+  MetricOptionProps,
+  ColumnOptionProps,
+} from '@superset-ui/chart-controls';
+
+const OptionContainer = styled.div`
+  .option-label {
+    display: inline-block;
+    & ~ i {
+      margin-left: ${({ theme }) => theme.gridUnit}px;
+    }
+  }
+  .type-label {
+    margin-right: ${({ theme }) => theme.gridUnit * 2}px;
+    width: ${({ theme }) => theme.gridUnit * 7}px;
+    display: inline-block;
+    text-align: center;
+    font-weight: ${({ theme }) => theme.typography.weights.bold};
+  }
+`;
+
+export const StyledMetricOption = (props: MetricOptionProps) => (
+  <OptionContainer>
+    <MetricOption {...props} />
+  </OptionContainer>
+);
+
+export const StyledColumnOption = (props: ColumnOptionProps) => (
+  <OptionContainer>
+    <ColumnOption {...props} />
+  </OptionContainer>
+);
diff --git a/superset-frontend/src/explore/controls.jsx b/superset-frontend/src/explore/controls.jsx
index c37f5e7..451ca52 100644
--- a/superset-frontend/src/explore/controls.jsx
+++ b/superset-frontend/src/explore/controls.jsx
@@ -64,9 +64,9 @@ import {
   legacyValidateInteger,
   validateNonEmpty,
 } from '@superset-ui/core';
-import { ColumnOption } from '@superset-ui/chart-controls';
 import { formatSelectOptions, mainMetric } from 'src/modules/utils';
 import { TIME_FILTER_LABELS } from './constants';
+import { StyledColumnOption } from './components/optionRenderers';
 
 const categoricalSchemeRegistry = getCategoricalSchemeRegistry();
 const sequentialSchemeRegistry = getSequentialSchemeRegistry();
@@ -124,8 +124,8 @@ const groupByControl = {
   default: [],
   includeTime: false,
   description: t('One or many controls to group by'),
-  optionRenderer: c => <ColumnOption column={c} showType />,
-  valueRenderer: c => <ColumnOption column={c} />,
+  optionRenderer: c => <StyledColumnOption column={c} showType />,
+  valueRenderer: c => <StyledColumnOption column={c} />,
   valueKey: 'column_name',
   allowAll: true,
   filterOption: ({ data: opt }, text) =>
@@ -308,8 +308,8 @@ export const controls = {
         'expression',
     ),
     clearable: false,
-    optionRenderer: c => <ColumnOption column={c} showType />,
-    valueRenderer: c => <ColumnOption column={c} />,
+    optionRenderer: c => <StyledColumnOption column={c} showType />,
+    valueRenderer: c => <StyledColumnOption column={c} />,
     valueKey: 'column_name',
     mapStateToProps: state => {
       const props = {};
diff --git a/superset-frontend/src/explore/main.less b/superset-frontend/src/explore/main.less
index f30435f..84ae27e 100644
--- a/superset-frontend/src/explore/main.less
+++ b/superset-frontend/src/explore/main.less
@@ -97,21 +97,6 @@
   margin-left: 3px;
 }
 
-.option-label {
-  display: inline-block;
-  & ~ i {
-    margin-left: 4px;
-  }
-}
-
-.type-label {
-  margin-right: 8px;
-  width: 30px;
-  display: inline-block;
-  text-align: center;
-  font-weight: @font-weight-bold;
-}
-
 .datasource-container {
   overflow: auto;
 }
@@ -124,25 +109,6 @@
   }
 }
 
-.adhoc-filter-edit-tabs > .nav-tabs {
-  margin-bottom: 8px;
-
-  & > li > a {
-    padding: 4px;
-  }
-}
-
-.edit-popover-resize {
-  transform: scaleX(-1);
-  -moz-transform: scaleX(-1);
-  -webkit-transform: scaleX(-1);
-  -ms-transform: scaleX(-1);
-  float: right;
-  margin-top: 18px;
-  margin-right: -10px;
-  cursor: nwse-resize;
-}
-
 #metrics-edit-popover {
   max-width: none;
 
@@ -151,32 +117,10 @@
   }
 }
 
-#filter-edit-popover {
-  max-width: none;
-}
-
-.filter-edit-clause-dropdown {
-  width: 120px;
-  margin-right: 5px;
-}
-
-.filter-edit-clause-info {
-  font-size: @font-size-xs;
-  padding-left: 5px;
-}
-
-.filter-edit-clause-section {
-  display: inline-flex;
-}
-
 .adhoc-option {
   cursor: pointer;
 }
 
-.adhoc-filter-sql-editor {
-  border: @gray-light solid thin;
-}
-
 .label-dropdown ul.dropdown-menu {
   position: fixed;
   top: auto;
@@ -193,10 +137,6 @@
   cursor: pointer;
 }
 
-.adhoc-filter-simple-column-dropdown {
-  margin-top: 20px;
-}
-
 .adhoc-label-arrow {
   font-size: @font-size-s;
   margin-left: 3px;
@@ -211,13 +151,6 @@
   }
 }
 
-.custom-sql-disabled-message {
-  color: @gray;
-  font-size: @font-size-xs;
-  text-align: center;
-  margin-top: 60px;
-}
-
 h1.section-header {
   font-size: @font-size-m;
   font-weight: @font-weight-bold;