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