From 214a59894e903783bb0bfb2f8759a276bc12167c Mon Sep 17 00:00:00 2001
From: Romeo Van Snick <romeo@romeovansnick.be>
Date: Wed, 15 May 2024 08:48:18 +0200
Subject: [PATCH] Info icon design update (#42557)

* Render item icon inline with column icon

* Use inline info icon in field picker

* Use new QueryColumnInfoIcon on filter columns picker

* Use new QueryColumnInfoIcon on suggestions dropdown

* Use new QueryColumnInfoIcon aggregations dropdown

* Use new QueryColumnInfoIcon filter modal

* Use new QueryColumnInfoIcon in BreakoutColumnListItem

* Use new QueryColumnInfoIcon in FieldList

* Use new QueryColumnInfoIcon in DataSelectorFieldPicker

* Update TableInfoIcon to render fallback too

* Use new TableInfoIcon in DataSelector

* Use new TableInfoIcon in ViewHeader

* Fix types in breakout column

* Move aria-label to wrapper

* Move binning back to the right

* Always give info icon full opacity

* Remove asDot props everywhere
---
 .../FieldPicker/FieldPicker.styled.tsx        | 12 +--
 .../components/FieldPicker/FieldPicker.tsx    | 11 +--
 .../BaseBucketPickerPopover.styled.tsx        |  6 +-
 .../BaseBucketPickerPopover.tsx               |  5 --
 .../BucketPickerPopover/types.ts              |  1 -
 .../QueryColumnPicker.styled.tsx              |  5 --
 .../QueryColumnPicker/QueryColumnPicker.tsx   | 21 ++----
 .../ColumnInfoIcon/ColumnInfoIcon.tsx         | 73 ++++++++++++-------
 .../MetadataInfo/InfoIcon/InfoIcon.styled.tsx | 22 ++++--
 .../TableInfoIcon/TableInfoIcon.tsx           | 27 +++++--
 .../DataSelectorFieldPicker.tsx               | 11 +--
 .../DataSelectorTablePicker.tsx               |  6 +-
 .../components/dataref/FieldList.tsx          |  7 +-
 .../ExpressionEditorSuggestions.styled.tsx    |  7 --
 .../ExpressionEditorSuggestions.tsx           | 21 +++---
 .../QuestionDataSource/QuestionDataSource.jsx | 14 +++-
 .../QuestionDataSource.styled.tsx             | 12 ++-
 .../BreakoutColumnListItem.styled.tsx         | 18 +----
 .../BreakoutColumnListItem.tsx                | 17 ++---
 .../FilterTitle/FilterTitle.styled.tsx        |  9 ---
 .../FilterModal/FilterTitle/FilterTitle.tsx   | 22 +++---
 .../FilterColumnPicker/FilterColumnPicker.tsx | 29 +++-----
 22 files changed, 167 insertions(+), 189 deletions(-)
 delete mode 100644 frontend/src/metabase/querying/components/FilterModal/FilterTitle/FilterTitle.styled.tsx

diff --git a/frontend/src/metabase/common/components/FieldPicker/FieldPicker.styled.tsx b/frontend/src/metabase/common/components/FieldPicker/FieldPicker.styled.tsx
index 20bc006ac34..cfe8e1567ca 100644
--- a/frontend/src/metabase/common/components/FieldPicker/FieldPicker.styled.tsx
+++ b/frontend/src/metabase/common/components/FieldPicker/FieldPicker.styled.tsx
@@ -1,27 +1,21 @@
 import styled from "@emotion/styled";
 
 import {
-  QueryColumnInfoIcon as _QueryColumnInfoIcon,
+  QueryColumnInfoIcon,
   HoverParent,
 } from "metabase/components/MetadataInfo/ColumnInfoIcon";
-import { color, alpha, darken } from "metabase/lib/colors";
-import { Icon } from "metabase/ui";
+import { color } from "metabase/lib/colors";
 
 export const ItemTitle = styled.div`
   min-width: 10ch;
 `;
 
-export const ItemIcon = styled(Icon)`
+export const ItemIcon = styled(QueryColumnInfoIcon)`
   margin: 0 0.5em;
   margin-left: 0.75em;
   color: ${color("text-dark")};
 `;
 
-export const QueryColumnInfoIcon = styled(_QueryColumnInfoIcon)`
-  color: ${alpha(darken(color("brand"), 0.6), 0.8)};
-  margin-left: auto;
-`;
-
 export const ItemList = styled.ul`
   padding: 0.5em;
 `;
diff --git a/frontend/src/metabase/common/components/FieldPicker/FieldPicker.tsx b/frontend/src/metabase/common/components/FieldPicker/FieldPicker.tsx
index 635c3933ac7..e25cbae732b 100644
--- a/frontend/src/metabase/common/components/FieldPicker/FieldPicker.tsx
+++ b/frontend/src/metabase/common/components/FieldPicker/FieldPicker.tsx
@@ -1,7 +1,6 @@
 import { useMemo } from "react";
 import { t } from "ttag";
 
-import { getColumnIcon } from "metabase/common/utils/columns";
 import { Checkbox, DelayGroup } from "metabase/ui";
 import * as Lib from "metabase-lib";
 
@@ -11,7 +10,6 @@ import {
   Label,
   ItemTitle,
   ItemIcon,
-  QueryColumnInfoIcon,
 } from "./FieldPicker.styled";
 
 interface FieldPickerProps {
@@ -89,15 +87,14 @@ export const FieldPicker = ({
                 }
                 onChange={event => onToggle(item.column, event.target.checked)}
               />
-
-              <ItemIcon name={getColumnIcon(item.column)} size={18} />
-              <ItemTitle>{item.columnInfo.displayName}</ItemTitle>
-              <QueryColumnInfoIcon
+              <ItemIcon
                 query={query}
                 stageIndex={stageIndex}
                 column={item.column}
-                position="right"
+                position="top-start"
+                size={18}
               />
+              <ItemTitle>{item.columnInfo.displayName}</ItemTitle>
             </Label>
           </li>
         ))}
diff --git a/frontend/src/metabase/common/components/QueryColumnPicker/BucketPickerPopover/BaseBucketPickerPopover.styled.tsx b/frontend/src/metabase/common/components/QueryColumnPicker/BucketPickerPopover/BaseBucketPickerPopover.styled.tsx
index 1699feeeef2..020ec0d7e60 100644
--- a/frontend/src/metabase/common/components/QueryColumnPicker/BucketPickerPopover/BaseBucketPickerPopover.styled.tsx
+++ b/frontend/src/metabase/common/components/QueryColumnPicker/BucketPickerPopover/BaseBucketPickerPopover.styled.tsx
@@ -20,7 +20,7 @@ export const ChevronDown = styled(Icon)`
   opacity: 0.75;
 `;
 
-export const TriggerButton = styled.button<{ hasDot?: boolean }>`
+export const TriggerButton = styled.button`
   display: flex;
   align-items: center;
   min-width: 0;
@@ -29,8 +29,8 @@ export const TriggerButton = styled.button<{ hasDot?: boolean }>`
   font-weight: 700;
   border-left: 2px solid transparent;
   padding: 0.5rem;
-  border-left: 2px solid
-    ${props => (props.hasDot ? "transparent" : alpha(color("border"), 0.1))};
+  border-left: 2px solid ${alpha(color("border"), 0.1)};
+  margin-left: auto;
 
   cursor: pointer;
 
diff --git a/frontend/src/metabase/common/components/QueryColumnPicker/BucketPickerPopover/BaseBucketPickerPopover.tsx b/frontend/src/metabase/common/components/QueryColumnPicker/BucketPickerPopover/BaseBucketPickerPopover.tsx
index b2b181177ed..4645fe973b1 100644
--- a/frontend/src/metabase/common/components/QueryColumnPicker/BucketPickerPopover/BaseBucketPickerPopover.tsx
+++ b/frontend/src/metabase/common/components/QueryColumnPicker/BucketPickerPopover/BaseBucketPickerPopover.tsx
@@ -11,7 +11,6 @@ import * as Lib from "metabase-lib";
 import {
   Content,
   ChevronDown,
-  Dot,
   MoreButton,
   SelectListItem,
   TriggerButton,
@@ -37,7 +36,6 @@ export interface BaseBucketPickerPopoverProps {
   isEditing: boolean;
   triggerLabel?: string;
   hasArrowIcon?: boolean;
-  hasDot?: boolean;
   hasChevronDown?: boolean;
   color?: ColorName;
   checkBucketIsSelected: (item: BucketListItem) => boolean;
@@ -57,7 +55,6 @@ function _BaseBucketPickerPopover({
   checkBucketIsSelected,
   renderTriggerContent,
   onSelect,
-  hasDot,
   hasChevronDown,
 }: BaseBucketPickerPopoverProps) {
   const [isOpened, setIsOpened] = useState(false);
@@ -101,7 +98,6 @@ function _BaseBucketPickerPopover({
       <Popover.Target>
         <TriggerButton
           aria-label={triggerLabel}
-          hasDot={hasDot}
           // Compat with E2E tests around MLv1-based components
           // Prefer using a11y role selectors
           data-testid="dimension-list-item-binning"
@@ -110,7 +106,6 @@ function _BaseBucketPickerPopover({
             setIsOpened(!isOpened);
           }}
         >
-          {hasDot && <Dot />}
           <Ellipsified>
             {renderTriggerContent(triggerContentBucketDisplayInfo)}
           </Ellipsified>
diff --git a/frontend/src/metabase/common/components/QueryColumnPicker/BucketPickerPopover/types.ts b/frontend/src/metabase/common/components/QueryColumnPicker/BucketPickerPopover/types.ts
index 84382458d05..68030685dd4 100644
--- a/frontend/src/metabase/common/components/QueryColumnPicker/BucketPickerPopover/types.ts
+++ b/frontend/src/metabase/common/components/QueryColumnPicker/BucketPickerPopover/types.ts
@@ -9,7 +9,6 @@ type CommonProps = Pick<
   | "isEditing"
   | "color"
   | "hasArrowIcon"
-  | "hasDot"
   | "hasChevronDown"
 >;
 
diff --git a/frontend/src/metabase/common/components/QueryColumnPicker/QueryColumnPicker.styled.tsx b/frontend/src/metabase/common/components/QueryColumnPicker/QueryColumnPicker.styled.tsx
index bafb40dac4e..6785e866dd6 100644
--- a/frontend/src/metabase/common/components/QueryColumnPicker/QueryColumnPicker.styled.tsx
+++ b/frontend/src/metabase/common/components/QueryColumnPicker/QueryColumnPicker.styled.tsx
@@ -1,6 +1,5 @@
 import styled from "@emotion/styled";
 
-import { QueryColumnInfoIcon } from "metabase/components/MetadataInfo/ColumnInfoIcon";
 import AccordionList from "metabase/core/components/AccordionList";
 import { color } from "metabase/lib/colors";
 import type { ColorName } from "metabase/lib/colors/types";
@@ -24,7 +23,3 @@ export const ColumnNameContainer = styled.div`
     overflow: hidden;
   }
 `;
-
-export const ColumnInfoIcon = styled(QueryColumnInfoIcon)`
-  align-self: center;
-`;
diff --git a/frontend/src/metabase/common/components/QueryColumnPicker/QueryColumnPicker.tsx b/frontend/src/metabase/common/components/QueryColumnPicker/QueryColumnPicker.tsx
index 337b9618f3e..43330ab05df 100644
--- a/frontend/src/metabase/common/components/QueryColumnPicker/QueryColumnPicker.tsx
+++ b/frontend/src/metabase/common/components/QueryColumnPicker/QueryColumnPicker.tsx
@@ -5,16 +5,17 @@ import {
   getColumnGroupIcon,
   getColumnGroupName,
 } from "metabase/common/utils/column-groups";
-import { getColumnIcon } from "metabase/common/utils/columns";
-import { HoverParent } from "metabase/components/MetadataInfo/ColumnInfoIcon";
+import {
+  QueryColumnInfoIcon,
+  HoverParent,
+} from "metabase/components/MetadataInfo/ColumnInfoIcon";
 import type { ColorName } from "metabase/lib/colors/types";
 import type { IconName } from "metabase/ui";
-import { Box, DelayGroup, Icon } from "metabase/ui";
+import { Box, DelayGroup } from "metabase/ui";
 import * as Lib from "metabase-lib";
 
 import { BucketPickerPopover } from "./BucketPickerPopover";
 import {
-  ColumnInfoIcon,
   ColumnNameContainer,
   StyledAccordionList,
 } from "./QueryColumnPicker.styled";
@@ -154,7 +155,6 @@ export function QueryColumnPicker({
             isEditing={checkIsColumnSelected(item)}
             hasBinning={hasBinning}
             hasTemporalBucketing={hasTemporalBucketing}
-            hasDot={withInfoIcons}
             hasChevronDown={withInfoIcons}
             color={color}
             onSelect={handleSelect}
@@ -174,13 +174,13 @@ export function QueryColumnPicker({
     ],
   );
 
-  const renderItemExtra = useCallback(
+  const renderItemIcon = useCallback(
     (item: ColumnListItem) => (
-      <ColumnInfoIcon
+      <QueryColumnInfoIcon
         query={query}
         stageIndex={stageIndex}
         column={item.column}
-        position="right"
+        position="top-start"
       />
     ),
     [query, stageIndex],
@@ -198,7 +198,6 @@ export function QueryColumnPicker({
         renderItemName={renderItemName}
         renderItemDescription={omitItemDescription}
         renderItemIcon={renderItemIcon}
-        renderItemExtra={renderItemExtra}
         renderItemLabel={renderItemLabel}
         color={color}
         maxHeight={Infinity}
@@ -228,7 +227,3 @@ function renderItemWrapper(content: ReactNode) {
 function omitItemDescription() {
   return null;
 }
-
-function renderItemIcon(item: ColumnListItem) {
-  return <Icon name={getColumnIcon(item.column)} size={18} />;
-}
diff --git a/frontend/src/metabase/components/MetadataInfo/ColumnInfoIcon/ColumnInfoIcon.tsx b/frontend/src/metabase/components/MetadataInfo/ColumnInfoIcon/ColumnInfoIcon.tsx
index 253a4852f9b..75e4a9ad6b9 100644
--- a/frontend/src/metabase/components/MetadataInfo/ColumnInfoIcon/ColumnInfoIcon.tsx
+++ b/frontend/src/metabase/components/MetadataInfo/ColumnInfoIcon/ColumnInfoIcon.tsx
@@ -1,5 +1,7 @@
 import { t } from "ttag";
 
+import { getColumnIcon } from "metabase/common/utils/columns";
+import type { IconName } from "metabase/ui";
 import * as Lib from "metabase-lib";
 
 import type {
@@ -10,55 +12,76 @@ import {
   QueryColumnInfoPopover,
   TableColumnInfoPopover,
 } from "../ColumnInfoPopover";
-import { PopoverHoverTarget, HoverParent } from "../InfoIcon";
+import {
+  PopoverHoverTarget,
+  PopoverDefaultIcon,
+  HoverParent,
+} from "../InfoIcon";
 export { HoverParent };
 
+type QueryColumnInfoIconProps = QueryColumnInfoPopoverProps & {
+  size?: number;
+  icon?: IconName;
+};
+
 export function QueryColumnInfoIcon({
   className,
   delay,
+  size,
+  icon,
   ...props
-}: QueryColumnInfoPopoverProps) {
+}: QueryColumnInfoIconProps) {
   const { query, stageIndex, column } = props;
   const { description = "" } = query
     ? Lib.displayInfo(query, stageIndex, column)
     : {};
 
-  if (!description) {
-    return null;
-  }
-
   return (
-    <QueryColumnInfoPopover {...props} delay={delay}>
-      <PopoverHoverTarget
-        className={className}
-        name="info_filled"
-        hasDescription={Boolean(description)}
-        aria-label={t`More info`}
-      />
-    </QueryColumnInfoPopover>
+    <>
+      <QueryColumnInfoPopover {...props} delay={delay}>
+        <span aria-label={t`More info`}>
+          <PopoverDefaultIcon
+            className={className}
+            name={icon ?? getColumnIcon(column)}
+            size={size}
+          />
+          <PopoverHoverTarget
+            className={className}
+            name="info_filled"
+            hasDescription={Boolean(description)}
+            size={size}
+          />
+        </span>
+      </QueryColumnInfoPopover>
+    </>
   );
 }
 
 QueryColumnInfoIcon.HoverParent = HoverParent;
 
+type TableColumnInfoIconProps = TableColumnInfoPopoverProps & {
+  icon: IconName;
+  size?: number;
+};
+
 export function TableColumnInfoIcon({
   className,
   delay,
   field,
+  icon,
+  size,
   ...props
-}: TableColumnInfoPopoverProps) {
-  if (!field.description) {
-    return null;
-  }
-
+}: TableColumnInfoIconProps) {
   return (
     <TableColumnInfoPopover {...props} field={field} delay={delay}>
-      <PopoverHoverTarget
-        className={className}
-        name="info_filled"
-        hasDescription={Boolean(field.description)}
-        aria-label={t`More info`}
-      />
+      <span aria-label={t`More info`}>
+        <PopoverDefaultIcon className={className} name={icon} size={size} />
+        <PopoverHoverTarget
+          className={className}
+          name="info_filled"
+          hasDescription={Boolean(field.description)}
+        />
+      </span>
     </TableColumnInfoPopover>
   );
 }
diff --git a/frontend/src/metabase/components/MetadataInfo/InfoIcon/InfoIcon.styled.tsx b/frontend/src/metabase/components/MetadataInfo/InfoIcon/InfoIcon.styled.tsx
index 683eb4a4c04..3c5dbaedcc2 100644
--- a/frontend/src/metabase/components/MetadataInfo/InfoIcon/InfoIcon.styled.tsx
+++ b/frontend/src/metabase/components/MetadataInfo/InfoIcon/InfoIcon.styled.tsx
@@ -3,18 +3,28 @@ import styled from "@emotion/styled";
 import { Icon } from "metabase/ui";
 
 export const PopoverHoverTarget = styled(Icon)<{ hasDescription: boolean }>`
-  padding: 0.7em 0.65em;
-  visibility: hidden;
   flex-shrink: 0;
-  opacity: ${props => (props.hasDescription ? 0.6 : 0.3)};
+  display: none;
 
-  &[aria-expanded="true"] {
-    opacity: 1;
+  [aria-expanded="true"] & {
+    display: block;
+  }
+`;
+
+export const PopoverDefaultIcon = styled(Icon)`
+  display: block;
+
+  [aria-expanded="true"] & {
+    display: none;
   }
 `;
 
 export const HoverParent = styled.div`
   &:hover ${PopoverHoverTarget} {
-    visibility: visible;
+    display: block;
+  }
+
+  &:hover ${PopoverDefaultIcon} {
+    display: none;
   }
 `;
diff --git a/frontend/src/metabase/components/MetadataInfo/TableInfoIcon/TableInfoIcon.tsx b/frontend/src/metabase/components/MetadataInfo/TableInfoIcon/TableInfoIcon.tsx
index 28a1138efb1..c07049ccc8b 100644
--- a/frontend/src/metabase/components/MetadataInfo/TableInfoIcon/TableInfoIcon.tsx
+++ b/frontend/src/metabase/components/MetadataInfo/TableInfoIcon/TableInfoIcon.tsx
@@ -1,28 +1,41 @@
 import { t } from "ttag";
 
-import { PopoverHoverTarget, HoverParent } from "../InfoIcon";
+import type { IconName } from "metabase/ui";
+
+import {
+  PopoverHoverTarget,
+  HoverParent,
+  PopoverDefaultIcon,
+} from "../InfoIcon";
 import type { TableInfoPopoverProps } from "../TableInfoPopover";
 import { TableInfoPopover } from "../TableInfoPopover";
 export { HoverParent };
 
 type TableInfoIconProps = TableInfoPopoverProps & {
   className?: string;
+  icon?: IconName;
+  size?: number;
 };
 
 export function TableInfoIcon({
   className,
   delay,
   table,
+  size,
+  icon = "table",
   ...props
 }: TableInfoIconProps) {
   return (
     <TableInfoPopover {...props} table={table} delay={delay}>
-      <PopoverHoverTarget
-        className={className}
-        name="info_filled"
-        hasDescription={Boolean(table.description)}
-        aria-label={t`More info`}
-      />
+      <span aria-label={t`More info`}>
+        <PopoverDefaultIcon name={icon} className={className} size={size} />
+        <PopoverHoverTarget
+          className={className}
+          name="info_filled"
+          hasDescription={Boolean(table.description)}
+          size={size}
+        />
+      </span>
     </TableInfoPopover>
   );
 }
diff --git a/frontend/src/metabase/query_builder/components/DataSelector/DataSelectorFieldPicker/DataSelectorFieldPicker.tsx b/frontend/src/metabase/query_builder/components/DataSelector/DataSelectorFieldPicker/DataSelectorFieldPicker.tsx
index 46e4067228c..27238dd4734 100644
--- a/frontend/src/metabase/query_builder/components/DataSelector/DataSelectorFieldPicker/DataSelectorFieldPicker.tsx
+++ b/frontend/src/metabase/query_builder/components/DataSelector/DataSelectorFieldPicker/DataSelectorFieldPicker.tsx
@@ -72,9 +72,11 @@ const DataSelectorFieldPicker = ({
 
   const renderItemIcon = (item: FieldWithName) =>
     item.field && (
-      <Icon
-        name={item.field.dimension().icon() as unknown as IconName}
+      <TableColumnInfoIcon
+        field={item.field}
+        position="top-end"
         size={18}
+        icon={item.field.dimension().icon() as unknown as IconName}
       />
     );
 
@@ -95,7 +97,6 @@ const DataSelectorFieldPicker = ({
           itemIsClickable={(item: FieldWithName) => item.field}
           renderItemWrapper={renderItemWrapper}
           renderItemIcon={renderItemIcon}
-          renderItemExtra={renderItemExtra}
         />
       </DelayGroup>
     </Container>
@@ -106,10 +107,6 @@ function renderItemWrapper(content: ReactNode) {
   return <HoverParent>{content}</HoverParent>;
 }
 
-function renderItemExtra(item: FieldWithName) {
-  return <TableColumnInfoIcon field={item.field} position="top-end" />;
-}
-
 const Header = ({ onBack, selectedTable }: HeaderProps) => (
   <HeaderContainer onClick={onBack}>
     <Icon name="chevronleft" size={18} />
diff --git a/frontend/src/metabase/query_builder/components/DataSelector/DataSelectorTablePicker/DataSelectorTablePicker.tsx b/frontend/src/metabase/query_builder/components/DataSelector/DataSelectorTablePicker/DataSelectorTablePicker.tsx
index cd991499178..20964f106f5 100644
--- a/frontend/src/metabase/query_builder/components/DataSelector/DataSelectorTablePicker/DataSelectorTablePicker.tsx
+++ b/frontend/src/metabase/query_builder/components/DataSelector/DataSelectorTablePicker/DataSelectorTablePicker.tsx
@@ -95,10 +95,7 @@ const DataSelectorTablePicker = ({
       table && selectedTable ? table.id === selectedTable.id : false;
 
     const renderItemIcon = ({ table }: { table: Table }) =>
-      table ? <Icon name="table" /> : null;
-
-    const renderItemExtra = ({ table }: { table: Table }) =>
-      table && <TableInfoIcon table={table} position="right" />;
+      table ? <TableInfoIcon table={table} position="top-start" /> : null;
 
     const renderItemWrapper = (content: ReactNode) => (
       <HoverParent>{content}</HoverParent>
@@ -127,7 +124,6 @@ const DataSelectorTablePicker = ({
             showSpinner={showSpinner}
             itemIsSelected={checkIfItemIsSelected}
             itemIsClickable={checkIfItemIsClickable}
-            renderItemExtra={renderItemExtra}
             renderItemIcon={renderItemIcon}
             renderItemWrapper={renderItemWrapper}
             showItemArrows={hasNextStep}
diff --git a/frontend/src/metabase/query_builder/components/dataref/FieldList.tsx b/frontend/src/metabase/query_builder/components/dataref/FieldList.tsx
index 9eff6030423..f203dac220f 100644
--- a/frontend/src/metabase/query_builder/components/dataref/FieldList.tsx
+++ b/frontend/src/metabase/query_builder/components/dataref/FieldList.tsx
@@ -1,4 +1,4 @@
-import { t, ngettext, msgid } from "ttag";
+import { ngettext, msgid } from "ttag";
 
 import type { IconName } from "metabase/ui";
 import { DelayGroup } from "metabase/ui";
@@ -8,7 +8,6 @@ import {
   NodeListItem,
   NodeListItemLink,
   NodeListItemName,
-  NodeListItemIcon,
   NodeListTitle,
   NodeListContainer,
   NodeListIcon,
@@ -38,13 +37,11 @@ const FieldList = ({ fields, onFieldClick }: FieldListProps) => (
         // field.icon() cannot be annotated to return IconName
         // because metabase-lib cannot import from metabase.
         const iconName = field.icon() as IconName;
-        const tooltip = iconName === "unknown" ? t`Unknown type` : null;
         return (
           <NodeListItem as="li" key={field.getUniqueId()}>
             <NodeListItemLink onClick={() => onFieldClick(field)}>
-              <NodeListItemIcon name={iconName} tooltip={tooltip} />
+              <NodeListInfoIcon field={field} position="left" icon={iconName} />
               <NodeListItemName>{field.name}</NodeListItemName>
-              <NodeListInfoIcon field={field} position="top-end" />
             </NodeListItemLink>
           </NodeListItem>
         );
diff --git a/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorSuggestions/ExpressionEditorSuggestions.styled.tsx b/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorSuggestions/ExpressionEditorSuggestions.styled.tsx
index 9c46c48bf35..6676104f5ab 100644
--- a/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorSuggestions/ExpressionEditorSuggestions.styled.tsx
+++ b/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorSuggestions/ExpressionEditorSuggestions.styled.tsx
@@ -1,7 +1,6 @@
 import { css } from "@emotion/react";
 import styled from "@emotion/styled";
 
-import { QueryColumnInfoIcon as BaseQueryColumnInfoIcon } from "metabase/components/MetadataInfo/ColumnInfoIcon";
 import {
   HoverParent,
   PopoverHoverTarget as BasePopoverHoverTarget,
@@ -71,12 +70,6 @@ export const SuggestionTitle = styled.span`
   margin-right: 1.5em;
 `;
 
-export const QueryColumnInfoIcon = styled(BaseQueryColumnInfoIcon)`
-  padding: 0;
-  margin-left: auto;
-  padding: 0.3125rem 0;
-`;
-
 export const PopoverHoverTarget = styled(BasePopoverHoverTarget)`
   padding: 0;
   margin-left: auto;
diff --git a/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorSuggestions/ExpressionEditorSuggestions.tsx b/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorSuggestions/ExpressionEditorSuggestions.tsx
index 72549de061b..2947880a6c5 100644
--- a/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorSuggestions/ExpressionEditorSuggestions.tsx
+++ b/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorSuggestions/ExpressionEditorSuggestions.tsx
@@ -9,6 +9,7 @@ import {
 import { t } from "ttag";
 import _ from "underscore";
 
+import { QueryColumnInfoIcon } from "metabase/components/MetadataInfo/ColumnInfoIcon";
 import { HoverParent } from "metabase/components/MetadataInfo/InfoIcon";
 import { Popover as InfoPopover } from "metabase/components/MetadataInfo/Popover";
 import CS from "metabase/css/core/index.css";
@@ -42,7 +43,6 @@ import {
   SuggestionMatch,
   SuggestionTitle,
   GroupTitle,
-  QueryColumnInfoIcon,
   PopoverHoverTarget,
 } from "./ExpressionEditorSuggestions.styled";
 
@@ -247,13 +247,22 @@ function ExpressionEditorSuggestionsListItem({
         className={cx(CS.hoverParent, CS.hoverInherit)}
         data-testid="expression-suggestions-list-item"
       >
-        {icon && (
+        {icon && (helpText || !suggestion.column) && (
           <Icon
             name={icon as IconName}
             color={isHighlighted ? highlighted : normal}
             className={CS.mr1}
           />
         )}
+        {!helpText && suggestion.column && (
+          <QueryColumnInfoIcon
+            query={query}
+            stageIndex={stageIndex}
+            column={suggestion.column}
+            position="top-start"
+            className={CS.mr1}
+          />
+        )}
         <SuggestionTitle>
           {suggestion.name.slice(0, start)}
           <SuggestionMatch>{suggestion.name.slice(start, end)}</SuggestionMatch>
@@ -272,14 +281,6 @@ function ExpressionEditorSuggestionsListItem({
             />
           </InfoPopover>
         )}
-        {!helpText && suggestion.column && (
-          <QueryColumnInfoIcon
-            query={query}
-            stageIndex={stageIndex}
-            column={suggestion.column}
-            position="right"
-          />
-        )}
       </ExpressionListItem>
     </HoverParent>
   );
diff --git a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/QuestionDataSource/QuestionDataSource.jsx b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/QuestionDataSource/QuestionDataSource.jsx
index 69158b2e785..e39513e68a7 100644
--- a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/QuestionDataSource/QuestionDataSource.jsx
+++ b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/QuestionDataSource/QuestionDataSource.jsx
@@ -2,6 +2,7 @@ import PropTypes from "prop-types";
 import { isValidElement } from "react";
 import { t } from "ttag";
 
+import { TableInfoIcon } from "metabase/components/MetadataInfo/TableInfoIcon/TableInfoIcon";
 import Tooltip from "metabase/core/components/Tooltip";
 import Collections from "metabase/entities/collections";
 import Questions from "metabase/entities/questions";
@@ -18,7 +19,7 @@ import * as ML_Urls from "metabase-lib/v1/urls";
 
 import { HeadBreadcrumbs } from "../HeaderBreadcrumbs";
 
-import { TablesDivider, TableInfoIcon } from "./QuestionDataSource.styled";
+import { TablesDivider, IconWrapper } from "./QuestionDataSource.styled";
 
 QuestionDataSource.propTypes = {
   question: PropTypes.object,
@@ -260,7 +261,16 @@ function QuestionTableBadges({ tables, subHead, hasLink, isLast }) {
     >
       <span>
         {table.displayName()}
-        {!subHead && <TableInfoIcon table={table} />}
+        {!subHead && (
+          <IconWrapper>
+            <TableInfoIcon
+              table={table}
+              icon="info_filled"
+              size={12}
+              position="bottom"
+            />
+          </IconWrapper>
+        )}
       </span>
     </HeadBreadcrumbs.Badge>
   ));
diff --git a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/QuestionDataSource/QuestionDataSource.styled.tsx b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/QuestionDataSource/QuestionDataSource.styled.tsx
index df6ae898043..24752dd3523 100644
--- a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/QuestionDataSource/QuestionDataSource.styled.tsx
+++ b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/QuestionDataSource/QuestionDataSource.styled.tsx
@@ -11,12 +11,10 @@ export const TablesDivider = styled.span`
   user-select: none;
 `;
 
-export const TableInfoIcon = styled(_TableInfoIcon)`
+export const IconWrapper = styled.span`
   color: ${color("text-light")};
-  visibility: visible;
-  font-size: min(1rem, 1em);
-  padding: 0;
-  margin-left: 0.5em;
-  position: relative;
-  top: 1px;
+  display: inline-block;
+  font-size: 1rem;
+  margin-left: 0.5rem;
+  vertical-align: middle;
 `;
diff --git a/frontend/src/metabase/query_builder/components/view/sidebars/SummarizeSidebar/BreakoutColumnList/BreakoutColumnListItem/BreakoutColumnListItem.styled.tsx b/frontend/src/metabase/query_builder/components/view/sidebars/SummarizeSidebar/BreakoutColumnList/BreakoutColumnListItem/BreakoutColumnListItem.styled.tsx
index 02806d81950..e5640572567 100644
--- a/frontend/src/metabase/query_builder/components/view/sidebars/SummarizeSidebar/BreakoutColumnList/BreakoutColumnListItem/BreakoutColumnListItem.styled.tsx
+++ b/frontend/src/metabase/query_builder/components/view/sidebars/SummarizeSidebar/BreakoutColumnList/BreakoutColumnListItem/BreakoutColumnListItem.styled.tsx
@@ -2,10 +2,9 @@ import { css } from "@emotion/react";
 import styled from "@emotion/styled";
 
 import { BucketPickerPopover } from "metabase/common/components/QueryColumnPicker/BucketPickerPopover";
-import { QueryColumnInfoIcon as BaseQueryColumnInfoIcon } from "metabase/components/MetadataInfo/ColumnInfoIcon";
+import { QueryColumnInfoIcon } from "metabase/components/MetadataInfo/ColumnInfoIcon";
 import Button from "metabase/core/components/Button";
 import { color, alpha } from "metabase/lib/colors";
-import { Icon } from "metabase/ui";
 
 export const Content = styled.div`
   display: flex;
@@ -55,7 +54,7 @@ AddButton.defaultProps = {
   borderless: true,
 };
 
-export const ColumnTypeIcon = styled(Icon)`
+export const ColumnTypeIcon = styled(QueryColumnInfoIcon)`
   color: ${color("text-medium")};
 `;
 
@@ -66,14 +65,9 @@ export const Title = styled.div`
   font-weight: 700;
 `;
 
-export const QueryColumnInfoIcon = styled(BaseQueryColumnInfoIcon)`
-  margin-left: auto;
-`;
-
 const selectedStyle = css`
   ${Content},
-  ${ColumnTypeIcon},
-  ${QueryColumnInfoIcon} {
+  ${ColumnTypeIcon} {
     background-color: ${color("summarize")};
     color: ${color("white")};
   }
@@ -81,8 +75,6 @@ const selectedStyle = css`
   ${BucketPickerPopover.TriggerButton} {
     opacity: 1;
     color: ${alpha("white", 0.65)};
-    padding-left: 0;
-    border-left: 0;
   }
 
   ${BucketPickerPopover.TriggerButton}:hover {
@@ -95,11 +87,9 @@ const unselectedStyle = css`
   ${BucketPickerPopover.TriggerButton} {
     opacity: 0;
     color: ${color("text-light")};
-    padding-left: 0;
-    border-left: 0;
   }
 
-  ${QueryColumnInfoIcon} {
+  ${ColumnTypeIcon} {
     color: ${color("text-light")};
   }
 
diff --git a/frontend/src/metabase/query_builder/components/view/sidebars/SummarizeSidebar/BreakoutColumnList/BreakoutColumnListItem/BreakoutColumnListItem.tsx b/frontend/src/metabase/query_builder/components/view/sidebars/SummarizeSidebar/BreakoutColumnList/BreakoutColumnListItem/BreakoutColumnListItem.tsx
index 0400b8aef8b..4346360b6e2 100644
--- a/frontend/src/metabase/query_builder/components/view/sidebars/SummarizeSidebar/BreakoutColumnList/BreakoutColumnListItem/BreakoutColumnListItem.tsx
+++ b/frontend/src/metabase/query_builder/components/view/sidebars/SummarizeSidebar/BreakoutColumnList/BreakoutColumnListItem/BreakoutColumnListItem.tsx
@@ -3,7 +3,6 @@ import { useCallback } from "react";
 import { t } from "ttag";
 
 import { BucketPickerPopover } from "metabase/common/components/QueryColumnPicker/BucketPickerPopover";
-import { getColumnIcon } from "metabase/common/utils/columns";
 import { HoverParent } from "metabase/components/MetadataInfo/ColumnInfoIcon";
 import Tooltip from "metabase/core/components/Tooltip";
 import * as Lib from "metabase-lib";
@@ -16,7 +15,6 @@ import {
   TitleContainer,
   RemoveButton,
   Root,
-  QueryColumnInfoIcon,
 } from "./BreakoutColumnListItem.styled";
 
 const STAGE_INDEX = -1;
@@ -72,7 +70,13 @@ export function BreakoutColumnListItem({
     >
       <Content onClick={handleListItemClick}>
         <TitleContainer>
-          <ColumnTypeIcon name={getColumnIcon(item.column)} size={18} />
+          <ColumnTypeIcon
+            query={query}
+            stageIndex={STAGE_INDEX}
+            column={item.column}
+            position="left"
+            size={18}
+          />
           <Title data-testid="dimension-list-item-name">{displayName}</Title>
           <BucketPickerPopover
             query={query}
@@ -80,7 +84,6 @@ export function BreakoutColumnListItem({
             column={item.column}
             color="summarize"
             isEditing={isSelected}
-            hasDot
             hasChevronDown
             hasBinning
             hasTemporalBucketing
@@ -88,12 +91,6 @@ export function BreakoutColumnListItem({
               breakout ? onUpdateColumn(column) : onAddColumn(column)
             }
           />
-          <QueryColumnInfoIcon
-            query={query}
-            stageIndex={STAGE_INDEX}
-            column={item.column}
-            position="top-end"
-          />
         </TitleContainer>
         {isSelected && (
           <RemoveButton
diff --git a/frontend/src/metabase/querying/components/FilterModal/FilterTitle/FilterTitle.styled.tsx b/frontend/src/metabase/querying/components/FilterModal/FilterTitle/FilterTitle.styled.tsx
deleted file mode 100644
index ff538bc215d..00000000000
--- a/frontend/src/metabase/querying/components/FilterModal/FilterTitle/FilterTitle.styled.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import styled from "@emotion/styled";
-
-export const InfoIconWrapper = styled.div`
-  position: relative;
-  left: 0.25rem;
-  width: 2rem;
-  display: flex;
-  align-items: center;
-`;
diff --git a/frontend/src/metabase/querying/components/FilterModal/FilterTitle/FilterTitle.tsx b/frontend/src/metabase/querying/components/FilterModal/FilterTitle/FilterTitle.tsx
index dc3ba3bdfd6..5f73d2371d5 100644
--- a/frontend/src/metabase/querying/components/FilterModal/FilterTitle/FilterTitle.tsx
+++ b/frontend/src/metabase/querying/components/FilterModal/FilterTitle/FilterTitle.tsx
@@ -5,13 +5,11 @@ import {
   QueryColumnInfoIcon,
 } from "metabase/components/MetadataInfo/ColumnInfoIcon";
 import type { IconName } from "metabase/ui";
-import { Flex, Icon } from "metabase/ui";
+import { Flex } from "metabase/ui";
 import type * as Lib from "metabase-lib";
 
 import { FilterColumnName } from "../FilterColumnName";
 
-import { InfoIconWrapper } from "./FilterTitle.styled";
-
 type FilterTitleProps = {
   children?: ReactNode;
   column: Lib.ColumnMetadata;
@@ -32,16 +30,14 @@ export function FilterTitle({
   stageIndex,
 }: FilterTitleProps) {
   return (
-    <Flex h="100%" align="center" gap="sm">
-      <InfoIconWrapper>
-        <QueryColumnInfoIcon
-          query={query}
-          stageIndex={stageIndex}
-          column={column}
-          position="left"
-        />
-      </InfoIconWrapper>
-      <Icon name={columnIcon} />
+    <Flex h="100%" align="center" gap="sm" pl="md">
+      <QueryColumnInfoIcon
+        query={query}
+        stageIndex={stageIndex}
+        column={column}
+        icon={columnIcon}
+        position="left"
+      />
       <FilterColumnName
         query={query}
         stageIndex={stageIndex}
diff --git a/frontend/src/metabase/querying/components/FilterPicker/FilterColumnPicker/FilterColumnPicker.tsx b/frontend/src/metabase/querying/components/FilterPicker/FilterColumnPicker/FilterColumnPicker.tsx
index 27d67bb64d4..bbad00042c9 100644
--- a/frontend/src/metabase/querying/components/FilterPicker/FilterColumnPicker/FilterColumnPicker.tsx
+++ b/frontend/src/metabase/querying/components/FilterPicker/FilterColumnPicker/FilterColumnPicker.tsx
@@ -5,7 +5,6 @@ import {
   getColumnGroupIcon,
   getColumnGroupName,
 } from "metabase/common/utils/column-groups";
-import { getColumnIcon } from "metabase/common/utils/columns";
 import {
   QueryColumnInfoIcon,
   HoverParent,
@@ -119,7 +118,6 @@ export function FilterColumnPicker({
         renderItemName={renderItemName}
         renderItemDescription={omitItemDescription}
         renderItemIcon={renderItemIcon}
-        renderItemExtra={renderItemExtra}
         // disable scrollbars inside the list
         style={{ overflow: "visible" }}
         maxHeight={Infinity}
@@ -148,26 +146,19 @@ function renderItemIcon(item: ColumnListItem | SegmentListItem) {
   }
 
   if (item.column) {
-    return <Icon name={getColumnIcon(item.column)} size={18} />;
+    const { query, stageIndex, column } = item;
+    return (
+      <QueryColumnInfoIcon
+        query={query}
+        stageIndex={stageIndex}
+        column={column}
+        position="top-start"
+        size={18}
+      />
+    );
   }
 }
 
 function renderItemWrapper(content: React.ReactNode) {
   return <HoverParent>{content}</HoverParent>;
 }
-
-function renderItemExtra(item: ColumnListItem | SegmentListItem) {
-  if (isSegmentListItem(item)) {
-    return null;
-  }
-
-  const { query, stageIndex, column } = item;
-  return (
-    <QueryColumnInfoIcon
-      query={query}
-      stageIndex={stageIndex}
-      column={column}
-      position="right"
-    />
-  );
-}
-- 
GitLab