Object icon visual parity (#19374)
## Summary Aligns **object metadata** icons with the **tinted tile** look everywhere we show a workspace object, and **retires** the navigation-only `NavigationMenuItemStyleIcon` wrapper in favor of **shared** UI primitives under `@/ui/display` and `@/object-metadata`. ## What changed ### Global tinted icon building blocks (`@/ui/display`) - **`TintedIconTile`** / **`StyledTintedIconTileContainer`** support optional **`size`** and **`stroke`**, and grow the tile when **`size`** is set so layouts match previous `theme.icon` usage. - Shared helpers and constants for theme color parsing and tinted backgrounds/borders/icon color (e.g. **`getTintedIconTileStyleFromColor`**, **`parseThemeColor`**, **`getColorFromTheme`**, related constants). ### Object metadata icon (`@/object-metadata`) - **`ObjectMetadataIcon`** composes **`TintedIconTile`** with **`getObjectColorWithFallback`**, forwards optional **`size`** / **`stroke`** for **visual parity** with old `getIcon` + explicit sizing. - **`getSelectOptionIconFromObjectMetadataItem`** returns an **`IconComponent`** for selects/menus that expect a component, not a React node. ### Navigation module cleanup - **Removed** **`NavigationMenuItemStyleIcon`**; call sites use **`ObjectMetadataIcon`**, **`TintedIconTile`**, and/or the shared **`getTintedIconTileStyleFromColor`** pipeline so the same treatment is **not** tied to the navigation package. - **`NavigationMenuItemIcon`**, view/link overlays, DnD handle, and sidebar editor flows updated to use the shared pattern where they render object (or tinted) icons. ### Product surfaces updated (non-exhaustive) - **Settings:** role object picker/rows, data model tables/graph/overview, object preview summary, webhooks entity list, morph relation multiselect. - **Workflows:** create/update/delete/upsert/find records, triggers, filters, variables dropdowns, AI agent object rows, object dropdowns. - **Shell:** side panel object filter / data sources / folder chrome where object icons appear. - **Records:** index header icon, show breadcrumb styling. - **Activity:** timeline event icon when linked object metadata applies. - **`NavigationDrawerItem`:** tinted branch aligned with shared **`TintedIconTile`** behavior. --------- Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
This commit is contained in:
@@ -1,16 +1,15 @@
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { NavigationMenuItemType } from 'twenty-shared/types';
|
||||
import { TintedIconTile, useIcons } from 'twenty-ui/display';
|
||||
|
||||
import { FOLDER_ICON_DEFAULT } from '@/navigation-menu-item/common/constants/FolderIconDefault';
|
||||
import { selectedNavigationMenuItemIdInEditModeState } from '@/navigation-menu-item/common/states/selectedNavigationMenuItemIdInEditModeState';
|
||||
import { useNavigationMenuItemSectionItems } from '@/navigation-menu-item/display/hooks/useNavigationMenuItemSectionItems';
|
||||
import { useUpdateFolderInDraft } from '@/navigation-menu-item/edit/folder/hooks/useUpdateFolderInDraft';
|
||||
import { SidePanelPageInfoLayout } from '@/side-panel/components/SidePanelPageInfoLayout';
|
||||
import { sidePanelPageInfoState } from '@/side-panel/states/sidePanelPageInfoState';
|
||||
import { sidePanelShouldFocusTitleInputComponentState } from '@/side-panel/states/sidePanelShouldFocusTitleInputComponentState';
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/display/components/NavigationMenuItemStyleIcon';
|
||||
import { FOLDER_ICON_DEFAULT } from '@/navigation-menu-item/common/constants/FolderIconDefault';
|
||||
import { NavigationMenuItemType } from 'twenty-shared/types';
|
||||
import { useUpdateFolderInDraft } from '@/navigation-menu-item/edit/folder/hooks/useUpdateFolderInDraft';
|
||||
import { useNavigationMenuItemSectionItems } from '@/navigation-menu-item/display/hooks/useNavigationMenuItemSectionItems';
|
||||
import { selectedNavigationMenuItemIdInEditModeState } from '@/navigation-menu-item/common/states/selectedNavigationMenuItemIdInEditModeState';
|
||||
import { IconPicker } from '@/ui/input/components/IconPicker';
|
||||
import { TitleInput } from '@/ui/input/components/TitleInput';
|
||||
import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState';
|
||||
@@ -78,7 +77,7 @@ export const SidePanelFolderInfo = () => {
|
||||
}
|
||||
clickableComponent={
|
||||
<StyledClickableIconWrapper>
|
||||
<NavigationMenuItemStyleIcon
|
||||
<TintedIconTile
|
||||
Icon={FolderIconComponent}
|
||||
color={selectedItem.color}
|
||||
/>
|
||||
|
||||
+5
-13
@@ -1,12 +1,11 @@
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useState } from 'react';
|
||||
import { OBJECTS_WITH_CHANNEL_VISIBILITY_CONSTRAINTS } from 'twenty-shared/constants';
|
||||
import { IconCube, useIcons } from 'twenty-ui/display';
|
||||
import { IconCube, TintedIconTile } from 'twenty-ui/display';
|
||||
import { MenuItemSelectAvatar, MenuItemToggle } from 'twenty-ui/navigation';
|
||||
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/display/components/NavigationMenuItemStyleIcon';
|
||||
import { ObjectMetadataIcon } from '@/object-metadata/components/ObjectMetadataIcon';
|
||||
import { useReadableObjectMetadataItems } from '@/object-metadata/hooks/useReadableObjectMetadataItems';
|
||||
import { getObjectColorWithFallback } from '@/object-metadata/utils/getObjectColorWithFallback';
|
||||
import { OBJECT_FILTER_DROPDOWN_ID } from '@/side-panel/components/SidePanelObjectFilterDropdown';
|
||||
import { sidePanelShowHiddenObjectsState } from '@/side-panel/states/sidePanelShowHiddenObjectsState';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
@@ -33,7 +32,6 @@ export const SidePanelObjectFilterDropdownContent = ({
|
||||
onSelectObject,
|
||||
}: SidePanelObjectFilterDropdownContentProps) => {
|
||||
const { t } = useLingui();
|
||||
const { getIcon } = useIcons();
|
||||
const [filterSearch, setFilterSearch] = useState('');
|
||||
const [sidePanelShowHiddenObjects, setSidePanelShowHiddenObjects] =
|
||||
useAtomState(sidePanelShowHiddenObjectsState);
|
||||
@@ -93,9 +91,7 @@ export const SidePanelObjectFilterDropdownContent = ({
|
||||
onEnter={() => handleSelect(null)}
|
||||
>
|
||||
<MenuItemSelectAvatar
|
||||
avatar={
|
||||
<NavigationMenuItemStyleIcon Icon={IconCube} color="gray" />
|
||||
}
|
||||
avatar={<TintedIconTile Icon={IconCube} />}
|
||||
text={t`All objects`}
|
||||
selected={selectedObjectNameSingular === null}
|
||||
onClick={() => handleSelect(null)}
|
||||
@@ -103,9 +99,6 @@ export const SidePanelObjectFilterDropdownContent = ({
|
||||
/>
|
||||
</SelectableListItem>
|
||||
{displayedObjects.map((objectMetadataItem) => {
|
||||
const ObjectIcon = getIcon(objectMetadataItem.icon);
|
||||
const iconColor = getObjectColorWithFallback(objectMetadataItem);
|
||||
|
||||
return (
|
||||
<SelectableListItem
|
||||
key={objectMetadataItem.id}
|
||||
@@ -114,9 +107,8 @@ export const SidePanelObjectFilterDropdownContent = ({
|
||||
>
|
||||
<MenuItemSelectAvatar
|
||||
avatar={
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={ObjectIcon}
|
||||
color={iconColor}
|
||||
<ObjectMetadataIcon
|
||||
objectMetadataItem={objectMetadataItem}
|
||||
/>
|
||||
}
|
||||
text={objectMetadataItem.labelPlural}
|
||||
|
||||
Reference in New Issue
Block a user