diff --git a/react-components/src/components/Architecture/CommandButton.tsx b/react-components/src/components/Architecture/CommandButton.tsx index b5220821880..480780363a4 100644 --- a/react-components/src/components/Architecture/CommandButton.tsx +++ b/react-components/src/components/Architecture/CommandButton.tsx @@ -10,7 +10,7 @@ import { type BaseCommand } from '../../architecture/base/commands/BaseCommand'; import { getButtonType, getDefaultCommand, getTooltipPlacement } from './utilities'; import { LabelWithShortcut } from './LabelWithShortcut'; import { type IconName } from '../../architecture/base/utilities/IconName'; -import { IconComponent } from './IconComponentMapper'; +import { IconComponent } from './Factories/IconFactory'; import { useOnUpdate } from './useOnUpdate'; import { type PlacementType } from './types'; import { TOOLTIP_DELAY } from './constants'; diff --git a/react-components/src/components/Architecture/DomainObjectPanel.tsx b/react-components/src/components/Architecture/DomainObjectPanel.tsx index 53e06582fc3..ade31ab0904 100644 --- a/react-components/src/components/Architecture/DomainObjectPanel.tsx +++ b/react-components/src/components/Architecture/DomainObjectPanel.tsx @@ -18,7 +18,7 @@ import { CommandButtons } from './Toolbar'; import { withSuppressRevealEvents } from '../../higher-order-components/withSuppressRevealEvents'; import { type TranslateDelegate } from '../../architecture/base/utilities/TranslateInput'; import { type UnitSystem } from '../../architecture/base/renderTarget/UnitSystem'; -import { IconComponent } from './IconComponentMapper'; +import { IconComponent } from './Factories/IconFactory'; const TEXT_SIZE = 'x-small'; const HEADER_SIZE = 'medium'; diff --git a/react-components/src/components/Architecture/IconComponentMapper.tsx b/react-components/src/components/Architecture/Factories/DefaultIcons.tsx similarity index 72% rename from react-components/src/components/Architecture/IconComponentMapper.tsx rename to react-components/src/components/Architecture/Factories/DefaultIcons.tsx index 78b648a4dfb..7198331ce51 100644 --- a/react-components/src/components/Architecture/IconComponentMapper.tsx +++ b/react-components/src/components/Architecture/Factories/DefaultIcons.tsx @@ -33,7 +33,7 @@ import { FlipVerticalIcon, FolderIcon, GrabIcon, - type IconProps, + LeafIcon, InfoIcon, LocationIcon, PerspectiveAltIcon, @@ -57,12 +57,11 @@ import { View360Icon, WaypointIcon } from '@cognite/cogs.js'; -import { type JSX, type FC } from 'react'; -import { type IconName } from '../../architecture/base/utilities/IconName'; -type IconType = FC; +import { type IconName } from '../../../architecture/base/utilities/IconName'; +import { type IconType } from './IconFactory'; -const defaultMappings: Array<[IconName, IconType]> = [ +export const DefaultIcons: Array<[IconName, IconType]> = [ ['Angle', AngleIcon], ['ArrowLeft', ArrowLeftIcon], ['ArrowRight', ArrowRightIcon], @@ -94,6 +93,7 @@ const defaultMappings: Array<[IconName, IconType]> = [ ['Folder', FolderIcon], ['Grab', GrabIcon], ['Info', InfoIcon], + ['Leaf', LeafIcon], ['Location', LocationIcon], ['Perspective', PerspectiveIcon], ['PerspectiveAlt', PerspectiveAltIcon], @@ -116,27 +116,3 @@ const defaultMappings: Array<[IconName, IconType]> = [ ['View360', View360Icon], ['Waypoint', WaypointIcon] ]; - -const DefaultIcon = (_iconProps: IconProps): JSX.Element => <>; - -export class IconComponentMapper { - private static readonly _iconMap = new Map(defaultMappings); - - public static addIcon(name: IconName, icon: IconType): void { - IconComponentMapper._iconMap.set(name, icon); - } - - public static getIcon(name: IconName): IconType { - if (name === undefined) { - return DefaultIcon; - } - return IconComponentMapper._iconMap.get(name) ?? DefaultIcon; - } -} - -type IconComponentProps = IconProps & { iconName: IconName }; - -export const IconComponent = ({ iconName, ...rest }: IconComponentProps): JSX.Element => { - const Icon = IconComponentMapper.getIcon(iconName); - return ; -}; diff --git a/react-components/src/components/Architecture/Factories/IconFactory.tsx b/react-components/src/components/Architecture/Factories/IconFactory.tsx new file mode 100644 index 00000000000..213d579d8fc --- /dev/null +++ b/react-components/src/components/Architecture/Factories/IconFactory.tsx @@ -0,0 +1,33 @@ +/*! + * Copyright 2024 Cognite AS + */ + +import { type JSX, type FC } from 'react'; +import { type IconName } from '../../../architecture/base/utilities/IconName'; +import { type IconProps } from '@cognite/cogs.js'; +import { DefaultIcons } from './DefaultIcons'; + +export type IconType = FC; + +const DefaultIcon = (_iconProps: IconProps): JSX.Element => <>; + +export class IconFactory { + private static readonly _icons = new Map(DefaultIcons); + public static install(iconName: IconName, iconType: IconType): void { + IconFactory._icons.set(iconName, iconType); + } + + public static getIcon(iconName: IconName): IconType { + if (iconName === undefined) { + return DefaultIcon; + } + return IconFactory._icons.get(iconName) ?? DefaultIcon; + } +} + +type IconComponentProps = IconProps & { iconName: IconName }; + +export const IconComponent = ({ iconName, ...rest }: IconComponentProps): JSX.Element => { + const Icon = IconFactory.getIcon(iconName); + return ; +}; diff --git a/react-components/src/components/Architecture/FilterButton.tsx b/react-components/src/components/Architecture/FilterButton.tsx index 56e4f2daf86..68d0c75ee59 100644 --- a/react-components/src/components/Architecture/FilterButton.tsx +++ b/react-components/src/components/Architecture/FilterButton.tsx @@ -20,7 +20,7 @@ import { BaseFilterCommand } from '../../architecture/base/commands/BaseFilterCo import { FilterItem } from './FilterItem'; import { OPTION_MIN_WIDTH, DEFAULT_PADDING, SELECT_DROPDOWN_ICON_COLOR } from './constants'; import { type IconName } from '../../architecture/base/utilities/IconName'; -import { IconComponent } from './IconComponentMapper'; +import { IconComponent } from './Factories/IconFactory'; import { TOOLBAR_HORIZONTAL_PANEL_OFFSET } from '../constants'; import { offset } from '@floating-ui/dom'; diff --git a/react-components/src/components/Architecture/SegmentedButtons.tsx b/react-components/src/components/Architecture/SegmentedButtons.tsx index 0f1fb592bc9..7c9ddb6ec14 100644 --- a/react-components/src/components/Architecture/SegmentedButtons.tsx +++ b/react-components/src/components/Architecture/SegmentedButtons.tsx @@ -10,7 +10,7 @@ import { type BaseCommand } from '../../architecture/base/commands/BaseCommand'; import { getDefaultCommand, getTooltipPlacement } from './utilities'; import { BaseOptionCommand } from '../../architecture/base/commands/BaseOptionCommand'; import { LabelWithShortcut } from './LabelWithShortcut'; -import { IconComponent } from './IconComponentMapper'; +import { IconComponent } from './Factories/IconFactory'; import { useOnUpdate } from './useOnUpdate'; import { type PlacementType } from './types'; import { TOOLTIP_DELAY } from './constants'; diff --git a/react-components/src/components/Architecture/SettingsButton.tsx b/react-components/src/components/Architecture/SettingsButton.tsx index 981bf0605d4..5f128b32d50 100644 --- a/react-components/src/components/Architecture/SettingsButton.tsx +++ b/react-components/src/components/Architecture/SettingsButton.tsx @@ -25,7 +25,7 @@ import { BaseFilterCommand } from '../../architecture/base/commands/BaseFilterCo import { FilterButton } from './FilterButton'; import { DEFAULT_PADDING, TOOLTIP_DELAY } from './constants'; import { type IconName } from '../../architecture/base/utilities/IconName'; -import { IconComponent } from './IconComponentMapper'; +import { IconComponent } from './Factories/IconFactory'; import { TOOLBAR_HORIZONTAL_PANEL_OFFSET } from '../constants'; diff --git a/react-components/src/components/Architecture/TreeView/components/TreeNodeIcon.tsx b/react-components/src/components/Architecture/TreeView/components/TreeNodeIcon.tsx index 0845cea102d..2897f69d8fe 100644 --- a/react-components/src/components/Architecture/TreeView/components/TreeNodeIcon.tsx +++ b/react-components/src/components/Architecture/TreeView/components/TreeNodeIcon.tsx @@ -4,7 +4,7 @@ import { type ReactElement } from 'react'; import { LoaderIcon } from '@cognite/cogs.js'; -import { IconComponentMapper } from '../../IconComponentMapper'; +import { IconFactory } from '../../Factories/IconFactory'; import { type ITreeNode } from '../../../../architecture/base/treeView/ITreeNode'; // ================================================== @@ -21,6 +21,6 @@ export const TreeNodeIcon = ({ if (!node.isSelected && node.iconColor !== undefined) { color = node.iconColor; } - const Icon = node.isLoadingChildren ? LoaderIcon : IconComponentMapper.getIcon(node.icon); + const Icon = node.isLoadingChildren ? LoaderIcon : IconFactory.getIcon(node.icon); return ; }; diff --git a/react-components/src/components/Architecture/index.ts b/react-components/src/components/Architecture/index.ts index b2449dc17bd..be1859e1129 100644 --- a/react-components/src/components/Architecture/index.ts +++ b/react-components/src/components/Architecture/index.ts @@ -4,7 +4,7 @@ export { RevealButtons } from './RevealButtons'; export type { PlacementType } from './types'; -export { IconComponentMapper } from './IconComponentMapper'; +export { IconFactory } from './Factories/IconFactory'; export { TreeView } from './TreeView/TreeView'; export type { TreeViewProps } from './TreeView/TreeViewProps'; export { ToolUI } from './ToolUI'; diff --git a/react-components/src/components/RevealToolbar/LayersButton/ModelLayersButton.tsx b/react-components/src/components/RevealToolbar/LayersButton/ModelLayersButton.tsx index 1e63b93cbf7..a94d27bf94b 100644 --- a/react-components/src/components/RevealToolbar/LayersButton/ModelLayersButton.tsx +++ b/react-components/src/components/RevealToolbar/LayersButton/ModelLayersButton.tsx @@ -6,7 +6,7 @@ import { Button } from '@cognite/cogs.js'; import { SelectPanel } from '@cognite/cogs-lab'; import { type ModelHandler } from './ModelHandler'; import { type ReactElement } from 'react'; -import { IconComponent } from '../../Architecture/IconComponentMapper'; +import { IconComponent } from '../../Architecture/Factories/IconFactory'; import { type IconName } from '../../../architecture/base/utilities/IconName'; import { ModelLayersList } from './ModelLayersList';