Fix Icon Lazy Loading (#2984)

Fix Icon picker
This commit is contained in:
Charles Bochet 2023-12-14 12:13:02 +01:00 committed by GitHub
parent ed2cd408bf
commit 8916dee352
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 4366 additions and 192 deletions

View File

@ -11,6 +11,7 @@ import { AppErrorBoundary } from '@/error-handler/components/AppErrorBoundary';
import { PromiseRejectionEffect } from '@/error-handler/components/PromiseRejectionEffect';
import { ApolloMetadataClientProvider } from '@/object-metadata/components/ApolloMetadataClientProvider';
import { ObjectMetadataItemsProvider } from '@/object-metadata/components/ObjectMetadataItemsProvider';
import { IconsProvider } from '@/ui/display/icon/components/IconsProvider';
import { DialogManager } from '@/ui/feedback/dialog-manager/components/DialogManager';
import { DialogManagerScope } from '@/ui/feedback/dialog-manager/scopes/DialogManagerScope';
import { SnackBarProvider } from '@/ui/feedback/snack-bar-manager/components/SnackBarProvider';
@ -34,31 +35,33 @@ root.render(
<RecoilDebugObserverEffect />
<BrowserRouter>
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
<ApolloProvider>
<HelmetProvider>
<ClientConfigProvider>
<UserProvider>
<ApolloMetadataClientProvider>
<ObjectMetadataItemsProvider>
<AppThemeProvider>
<SnackBarProvider>
<DialogManagerScope dialogManagerScopeId="dialog-manager">
<DialogManager>
<StrictMode>
<PromiseRejectionEffect />
<App />
</StrictMode>
</DialogManager>
</DialogManagerScope>
</SnackBarProvider>
</AppThemeProvider>
<PageChangeEffect />
</ObjectMetadataItemsProvider>
</ApolloMetadataClientProvider>
</UserProvider>
</ClientConfigProvider>
</HelmetProvider>
</ApolloProvider>
<IconsProvider>
<ApolloProvider>
<HelmetProvider>
<ClientConfigProvider>
<UserProvider>
<ApolloMetadataClientProvider>
<ObjectMetadataItemsProvider>
<AppThemeProvider>
<SnackBarProvider>
<DialogManagerScope dialogManagerScopeId="dialog-manager">
<DialogManager>
<StrictMode>
<PromiseRejectionEffect />
<App />
</StrictMode>
</DialogManager>
</DialogManagerScope>
</SnackBarProvider>
</AppThemeProvider>
<PageChangeEffect />
</ObjectMetadataItemsProvider>
</ApolloMetadataClientProvider>
</UserProvider>
</ClientConfigProvider>
</HelmetProvider>
</ApolloProvider>
</IconsProvider>
</SnackBarProviderScope>
</BrowserRouter>
</AppErrorBoundary>

View File

@ -5,7 +5,6 @@ import {
Attachment,
AttachmentType,
} from '@/activities/files/types/Attachment';
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import {
IconFile,
IconFileText,
@ -15,7 +14,8 @@ import {
IconPresentation,
IconTable,
IconVideo,
} from '@/ui/input/constants/icons';
} from '@/ui/display/icon';
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
const StyledIconContainer = styled.div<{ background: string }>`
align-items: center;

View File

@ -1,14 +1,13 @@
import { useLocation, useNavigate } from 'react-router-dom';
import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings';
import { Icon123 } from '@/ui/input/constants/icons';
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
export const ObjectMetadataNavItems = () => {
const { activeObjectMetadataItems } = useObjectMetadataItemForSettings();
const navigate = useNavigate();
const { icons } = useLazyLoadIcons();
const { getIcon } = useIcons();
const currentPath = useLocation().pathname;
return (
@ -20,9 +19,7 @@ export const ObjectMetadataNavItems = () => {
label={objectMetadataItem.labelPlural}
to={`/objects/${objectMetadataItem.namePlural}`}
active={currentPath == `/objects/${objectMetadataItem.namePlural}`}
Icon={
objectMetadataItem.icon ? icons[objectMetadataItem.icon] : Icon123
}
Icon={getIcon(objectMetadataItem.icon)}
onClick={() => {
navigate(`/objects/${objectMetadataItem.namePlural}`);
}}

View File

@ -10,7 +10,7 @@ import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObje
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { RecordTableActionBar } from '@/object-record/record-table/action-bar/components/RecordTableActionBar';
import { RecordTableContextMenu } from '@/object-record/record-table/context-menu/components/RecordTableContextMenu';
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { PageAddButton } from '@/ui/layout/page/PageAddButton';
import { PageBody } from '@/ui/layout/page/PageBody';
import { PageContainer } from '@/ui/layout/page/PageContainer';
@ -36,11 +36,14 @@ export const RecordTablePage = () => {
const navigate = useNavigate();
const { icons } = useLazyLoadIcons();
const { findObjectMetadataItemByNamePlural } =
useObjectMetadataItemForSettings();
const { getIcon } = useIcons();
const Icon = getIcon(
findObjectMetadataItemByNamePlural(objectNamePlural)?.icon,
);
useEffect(() => {
if (
!isNonEmptyString(objectNamePlural) &&
@ -64,12 +67,7 @@ export const RecordTablePage = () => {
title={
objectNamePlural.charAt(0).toUpperCase() + objectNamePlural.slice(1)
}
Icon={
icons[
findObjectMetadataItemByNamePlural(objectNamePlural)!.icon ??
'Icon123'
]
}
Icon={Icon}
>
<PageHotkeysEffect onAddButtonClick={handleAddButtonClick} />
<PageAddButton onClick={handleAddButtonClick} />

View File

@ -1,6 +1,6 @@
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
@ -15,7 +15,7 @@ export const ObjectFilterDropdownFilterSelect = () => {
availableFilterDefinitions,
} = useFilterDropdown();
const { icons } = useLazyLoadIcons();
const { getIcon } = useIcons();
const setHotkeyScope = useSetHotkeyScope();
@ -40,7 +40,7 @@ export const ObjectFilterDropdownFilterSelect = () => {
setObjectFilterDropdownSearchInput('');
}}
LeftIcon={icons[availableFilterDefinition.iconName]}
LeftIcon={getIcon(availableFilterDefinition.iconName)}
text={availableFilterDefinition.label}
/>
))}

View File

@ -3,8 +3,8 @@ import { useCallback, useState } from 'react';
import { useSortDropdown } from '@/object-record/object-sort-dropdown/hooks/useSortDropdown';
import { ObjectSortDropdownScope } from '@/object-record/object-sort-dropdown/scopes/ObjectSortDropdownScope';
import { IconChevronDown } from '@/ui/display/icon';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { LightButton } from '@/ui/input/button/components/LightButton';
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
@ -68,7 +68,7 @@ export const ObjectSortDropdownButton = ({
resetState();
};
const { icons } = useLazyLoadIcons();
const { getIcon } = useIcons();
return (
<ObjectSortDropdownScope sortScopeId={sortDropdownId}>
@ -117,7 +117,7 @@ export const ObjectSortDropdownButton = ({
testId={`select-sort-${index}`}
key={index}
onClick={() => handleAddSort(availableSortDefinition)}
LeftIcon={icons[availableSortDefinition.iconName]}
LeftIcon={getIcon(availableSortDefinition.iconName)}
text={availableSortDefinition.label}
/>
))}

View File

@ -1,7 +1,7 @@
import { useContext } from 'react';
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { FieldDisplay } from '../../field/components/FieldDisplay';
import { FieldInput } from '../../field/components/FieldInput';
@ -59,7 +59,7 @@ export const RecordInlineCell = () => {
closeInlineCell();
};
const { icons } = useLazyLoadIcons();
const { getIcon } = useIcons();
return (
<RecordInlineCellContainer
@ -71,7 +71,7 @@ export const RecordInlineCell = () => {
}
: undefined
}
IconLabel={icons[fieldDefinition.iconName]}
IconLabel={getIcon(fieldDefinition.iconName)}
editModeContent={
<FieldInput
onEnter={handleEnter}

View File

@ -2,7 +2,7 @@ import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { ColumnDefinition } from '../types/ColumnDefinition';
@ -39,14 +39,14 @@ const StyledText = styled.span`
export const ColumnHead = ({ column }: ColumnHeadProps) => {
const theme = useTheme();
const { icons, isLoadingIcons } = useLazyLoadIcons();
const Icon = icons[column.iconName];
const { getIcon } = useIcons();
const Icon = getIcon(column.iconName);
return (
<>
<StyledTitle>
<StyledIcon>
{!isLoadingIcons && <Icon size={theme.icon.size.md} />}
<Icon size={theme.icon.size.md} />
</StyledIcon>
<StyledText>{column.label}</StyledText>
</StyledTitle>

View File

@ -4,7 +4,7 @@ import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { IconSettings } from '@/ui/display/icon';
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
@ -22,8 +22,7 @@ export const RecordTableHeaderPlusButtonContent = () => {
const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector);
const { icons } = useLazyLoadIcons();
const { getIcon } = useIcons();
const { handleColumnVisibilityChange } = useTableColumns();
const handleAddColumn = useCallback(
@ -46,7 +45,7 @@ export const RecordTableHeaderPlusButtonContent = () => {
<MenuItem
key={column.fieldMetadataId}
onClick={() => handleAddColumn(column)}
LeftIcon={icons[column.iconName]}
LeftIcon={getIcon(column.iconName)}
text={column.label}
/>
))}

View File

@ -1,5 +1,5 @@
import { IconDeviceFloppy } from '@/ui/display/icon';
import { Button } from '@/ui/input/button/components/Button';
import { IconDeviceFloppy } from '@/ui/input/constants/icons';
type SaveButtonProps = {
onSave?: () => void;

View File

@ -2,10 +2,10 @@ import styled from '@emotion/styled';
import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings';
import { validateMetadataLabel } from '@/object-metadata/utils/validateMetadataLabel';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { IconPicker } from '@/ui/input/components/IconPicker';
import { Select } from '@/ui/input/components/Select';
import { TextInput } from '@/ui/input/components/TextInput';
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { Field } from '~/generated-metadata/graphql';
import { relationTypes } from '../constants/relationTypes';
@ -56,7 +56,7 @@ export const SettingsObjectFieldRelationForm = ({
onChange,
values,
}: SettingsObjectFieldRelationFormProps) => {
const { icons } = useLazyLoadIcons();
const { getIcon } = useIcons();
const { objectMetadataItems, findObjectMetadataItemById } =
useObjectMetadataItemForSettings();
@ -92,9 +92,7 @@ export const SettingsObjectFieldRelationForm = ({
options={objectMetadataItems.map((objectMetadataItem) => ({
label: objectMetadataItem.labelPlural,
value: objectMetadataItem.id,
Icon: objectMetadataItem.icon
? icons[objectMetadataItem.icon]
: undefined,
Icon: getIcon(objectMetadataItem.icon),
}))}
onChange={(value) => onChange({ objectMetadataId: value })}
/>

View File

@ -1,5 +1,5 @@
import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings';
import { useLazyLoadIcon } from '@/ui/input/hooks/useLazyLoadIcon';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { Field, FieldMetadataType } from '~/generated-metadata/graphql';
import { settingsFieldMetadataTypes } from '../constants/settingsFieldMetadataTypes';
@ -22,8 +22,9 @@ export const useFieldPreview = ({
const { findObjectMetadataItemById } = useObjectMetadataItemForSettings();
const objectMetadataItem = findObjectMetadataItemById(objectMetadataId);
const { Icon: ObjectIcon } = useLazyLoadIcon(objectMetadataItem?.icon ?? '');
const { Icon: FieldIcon } = useLazyLoadIcon(fieldMetadata.icon ?? '');
const { getIcon } = useIcons();
const ObjectIcon = getIcon(objectMetadataItem?.icon);
const FieldIcon = getIcon(fieldMetadata.icon);
const fieldName = fieldMetadata.id
? objectMetadataItem?.fields.find(({ id }) => id === fieldMetadata.id)?.name

View File

@ -2,8 +2,8 @@ import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { Checkbox } from '@/ui/input/components/Checkbox';
import { useLazyLoadIcon } from '@/ui/input/hooks/useLazyLoadIcon';
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
@ -41,7 +41,8 @@ export const SettingsAvailableStandardObjectItemTableRow = ({
}: SettingsAvailableStandardObjectItemTableRowProps) => {
const theme = useTheme();
const { Icon } = useLazyLoadIcon(objectItem.icon ?? '');
const { getIcon } = useIcons();
const Icon = getIcon(objectItem.icon);
return (
<StyledAvailableStandardObjectTableRow

View File

@ -2,10 +2,10 @@ import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { IconArchive, IconDotsVertical, IconPencil } from '@/ui/display/icon';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { Tag } from '@/ui/display/tag/components/Tag';
import { H2Title } from '@/ui/display/typography/components/H2Title';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { useLazyLoadIcon } from '@/ui/input/hooks/useLazyLoadIcon';
import { Card } from '@/ui/layout/card/components/Card';
import { CardContent } from '@/ui/layout/card/components/CardContent';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
@ -53,7 +53,8 @@ export const SettingsAboutSection = ({
onEdit,
}: SettingsAboutSectionProps) => {
const theme = useTheme();
const { Icon } = useLazyLoadIcon(iconKey);
const { getIcon } = useIcons();
const Icon = getIcon(iconKey);
const { closeDropdown } = useDropdown({ dropdownScopeId });

View File

@ -6,7 +6,7 @@ import styled from '@emotion/styled';
import { useRelationMetadata } from '@/object-metadata/hooks/useRelationMetadata';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
import { useLazyLoadIcon } from '@/ui/input/hooks/useLazyLoadIcon';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
@ -39,7 +39,8 @@ export const SettingsObjectFieldItemTableRow = ({
fieldMetadataItem: fieldMetadataItem,
}: SettingsObjectFieldItemTableRowProps) => {
const theme = useTheme();
const { Icon } = useLazyLoadIcon(fieldMetadataItem.icon ?? '');
const { getIcon } = useIcons();
const Icon = getIcon(fieldMetadataItem.icon);
const navigate = useNavigate();
// TODO: parse with zod and merge types with FieldType (create a subset of FieldType for example)

View File

@ -4,8 +4,8 @@ import styled from '@emotion/styled';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { Tag } from '@/ui/display/tag/components/Tag';
import { useLazyLoadIcon } from '@/ui/input/hooks/useLazyLoadIcon';
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
@ -40,7 +40,8 @@ export const SettingsObjectItemTableRow = ({
objectNameSingular: objectItem.nameSingular,
});
const { Icon } = useLazyLoadIcon(objectItem.icon ?? '');
const { getIcon } = useIcons();
const Icon = getIcon(objectItem.icon);
return (
<StyledObjectTableRow key={objectItem.namePlural} onClick={onClick}>

View File

@ -1,9 +1,9 @@
import styled from '@emotion/styled';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import { H2Title } from '@/ui/display/typography/components/H2Title';
import { IconPicker } from '@/ui/input/components/IconPicker';
import { useLazyLoadIcon } from '@/ui/input/hooks/useLazyLoadIcon';
import { Section } from '@/ui/layout/section/components/Section';
import ArrowRight from '../assets/ArrowRight.svg';
@ -36,7 +36,8 @@ export const SettingsObjectIconSection = ({
label,
onChange,
}: SettingsObjectIconSectionProps) => {
const { Icon } = useLazyLoadIcon(iconKey);
const { getIcon } = useIcons();
const Icon = getIcon(iconKey);
return (
<Section>

View File

@ -1,6 +1,5 @@
import { IconDotsVertical } from '@/ui/display/icon';
import { IconArchiveOff, IconDotsVertical } from '@/ui/display/icon';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { IconArchiveOff } from '@/ui/input/constants/icons';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';

View File

@ -0,0 +1,20 @@
import { useEffect } from 'react';
import { useSetRecoilState } from 'recoil';
import { iconsState } from '@/ui/display/icon/states/iconsState';
type IconsProviderProps = {
children: JSX.Element;
};
export const IconsProvider = ({ children }: IconsProviderProps) => {
const setIcons = useSetRecoilState(iconsState);
useEffect(() => {
import('../constants/index').then((lazyLoadedIcons) => {
setIcons(lazyLoadedIcons.default);
});
}, [setIcons]);
return children;
};

View File

@ -0,0 +1,20 @@
import { useRecoilValue } from 'recoil';
import { Icon123 } from '@/ui/display/icon';
import { iconsState } from '@/ui/display/icon/states/iconsState';
export const useIcons = () => {
const icons = useRecoilValue(iconsState);
const defaultIcon = Icon123;
const getIcons = () => {
return icons;
};
const getIcon = (iconKey?: string | null) => {
if (!iconKey) return defaultIcon;
return icons[iconKey] ?? defaultIcon;
};
return { getIcons, getIcon };
};

View File

@ -1,8 +1,10 @@
/* eslint-disable no-restricted-imports */
export type { TablerIconsProps } from '@tabler/icons-react';
export {
Icon123,
IconAlertCircle,
IconAlertTriangle,
IconApps,
IconArchive,
IconArchiveOff,
IconArrowDown,
@ -36,19 +38,25 @@ export {
IconCopy,
IconCurrencyDollar,
IconDatabase,
IconDeviceFloppy,
IconDotsVertical,
IconDownload,
IconEye,
IconEyeOff,
IconFile,
IconFileCheck,
IconFileImport,
IconFileText,
IconFileUpload,
IconFileZip,
IconForbid,
IconGripVertical,
IconHeadphones,
IconHeart,
IconHeartOff,
IconHelpCircle,
IconHierarchy2,
IconInfoCircle,
IconKey,
IconLanguage,
IconLayoutKanban,
@ -70,8 +78,10 @@ export {
IconPaperclip,
IconPencil,
IconPhone,
IconPhoto,
IconPlug,
IconPlus,
IconPresentation,
IconProgressCheck,
IconRelationManyToMany,
IconRelationOneToMany,
@ -80,6 +90,7 @@ export {
IconRobot,
IconSearch,
IconSettings,
IconTable,
IconTag,
IconTarget,
IconTargetArrow,
@ -90,5 +101,7 @@ export {
IconUser,
IconUserCircle,
IconUsers,
IconVideo,
IconWorld,
IconX,
} from '@tabler/icons-react';

View File

@ -1,6 +1,8 @@
import { useMemo, useState } from 'react';
import styled from '@emotion/styled';
import { IconApps } from '@/ui/display/icon';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
@ -16,9 +18,6 @@ import { arrayToChunks } from '~/utils/array/array-to-chunks';
import { IconButton, IconButtonVariant } from '../button/components/IconButton';
import { LightIconButton } from '../button/components/LightIconButton';
import { IconApps } from '../constants/icons';
import { useLazyLoadIcons } from '../hooks/useLazyLoadIcons';
import { DropdownMenuSkeletonItem } from '../relation-picker/components/skeletons/DropdownMenuSkeletonItem';
import { IconPickerHotkeyScope } from '../types/IconPickerHotkeyScope';
type IconPickerProps = {
@ -95,7 +94,8 @@ export const IconPicker = ({
const { closeDropdown } = useDropdown({ dropdownScopeId });
const { icons, isLoadingIcons: isLoading } = useLazyLoadIcons();
const { getIcons, getIcon } = useIcons();
const { icons } = getIcons();
const iconKeys = useMemo(() => {
const filteredIconKeys = Object.keys(icons).filter((iconKey) => {
@ -128,7 +128,7 @@ export const IconPicker = ({
clickableComponent={
<IconButton
disabled={disabled}
Icon={selectedIconKey ? icons[selectedIconKey] : IconApps}
Icon={selectedIconKey ? getIcon(selectedIconKey) : IconApps}
variant={variant}
/>
}
@ -139,7 +139,7 @@ export const IconPicker = ({
selectableItemIds={iconKeys2d}
hotkeyScope={IconPickerHotkeyScope.IconPicker}
onEnter={(iconKey) => {
onChange({ iconKey, Icon: icons[iconKey] });
onChange({ iconKey, Icon: getIcon(iconKey) });
closeDropdown();
}}
>
@ -159,24 +159,20 @@ export const IconPicker = ({
onMouseLeave={goBackToPreviousHotkeyScope}
>
<DropdownMenuItemsContainer>
{isLoading ? (
<DropdownMenuSkeletonItem />
) : (
<StyledMenuIconItemsContainer>
{iconKeys.map((iconKey) => (
<IconPickerIcon
key={iconKey}
iconKey={iconKey}
onClick={() => {
onChange({ iconKey, Icon: icons[iconKey] });
closeDropdown();
}}
selectedIconKey={selectedIconKey}
Icon={icons[iconKey]}
/>
))}
</StyledMenuIconItemsContainer>
)}
<StyledMenuIconItemsContainer>
{iconKeys.map((iconKey) => (
<IconPickerIcon
key={iconKey}
iconKey={iconKey}
onClick={() => {
onChange({ iconKey, Icon: getIcon(iconKey) });
closeDropdown();
}}
selectedIconKey={selectedIconKey}
Icon={getIcon(iconKey)}
/>
))}
</StyledMenuIconItemsContainer>
</DropdownMenuItemsContainer>
</div>
</DropdownMenu>

View File

@ -6,8 +6,7 @@ import { hasFlag } from 'country-flag-icons';
import * as Flags from 'country-flag-icons/react/3x2';
import { CountryCallingCode } from 'libphonenumber-js';
import { IconChevronDown } from '@/ui/display/icon';
import { IconWorld } from '@/ui/input/constants/icons';
import { IconChevronDown, IconWorld } from '@/ui/display/icon';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';

View File

@ -1,22 +0,0 @@
import { useEffect, useState } from 'react';
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import { useLazyLoadIcons } from './useLazyLoadIcons';
export const useLazyLoadIcon = (iconKey: string) => {
const { isLoadingIcons, icons } = useLazyLoadIcons();
const [Icon, setIcon] = useState<IconComponent | undefined>();
const [isLoadingIcon, setIsLoadingIcon] = useState(true);
useEffect(() => {
if (!iconKey) return;
if (!isLoadingIcons) {
setIcon(icons[iconKey]);
setIsLoadingIcon(false);
}
}, [iconKey, icons, isLoadingIcons]);
return { Icon, isLoadingIcon };
};

View File

@ -1,18 +0,0 @@
import { useEffect, useState } from 'react';
import { useRecoilState } from 'recoil';
import { iconsState } from '@/ui/input/states/iconsState';
export const useLazyLoadIcons = () => {
const [icons, setIcons] = useRecoilState(iconsState);
const [isLoadingIcons, setIsLoadingIcons] = useState(true);
useEffect(() => {
import('../constants/icons').then((lazyLoadedIcons) => {
setIcons(lazyLoadedIcons);
setIsLoadingIcons(false);
});
}, [setIcons]);
return { icons, isLoadingIcons };
};

View File

@ -1,9 +1,8 @@
import { atom } from 'recoil';
import { IconApps } from '@/ui/display/icon';
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import { IconApps } from '../constants/icons';
type IconPickerState = {
Icon: IconComponent;
iconKey: string;

View File

@ -1,5 +1,5 @@
import { getOperandLabelShort } from '@/object-record/object-filter-dropdown/utils/getOperandLabel';
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
import { ViewFilter } from '@/views/types/ViewFilter';
@ -12,7 +12,7 @@ export const EditableFilterChip = ({
viewFilter,
onRemove,
}: EditableFilterChipProps) => {
const { icons } = useLazyLoadIcons();
const { getIcon } = useIcons();
return (
<SortOrFilterChip
key={viewFilter.fieldMetadataId}
@ -21,7 +21,7 @@ export const EditableFilterChip = ({
labelValue={`${getOperandLabelShort(viewFilter.operand)} ${
viewFilter.displayValue
}`}
Icon={icons[viewFilter.definition.iconName]}
Icon={getIcon(viewFilter.definition.iconName)}
onRemove={onRemove}
/>
);

View File

@ -9,9 +9,9 @@ import {
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { IconMinus, IconPlus } from '@/ui/display/icon';
import { IconInfoCircle } from '@/ui/display/icon';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { AppTooltip } from '@/ui/display/tooltip/AppTooltip';
import { IconInfoCircle } from '@/ui/input/constants/icons';
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem';
import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
@ -51,7 +51,7 @@ export const ViewFieldsVisibilityDropdownSection = ({
else setOpenToolTipIndex(index);
};
const { icons } = useLazyLoadIcons();
const { getIcon } = useIcons();
const getIconButtons = (
index: number,
@ -108,7 +108,7 @@ export const ViewFieldsVisibilityDropdownSection = ({
itemComponent={
<MenuItemDraggable
key={field.fieldMetadataId}
LeftIcon={icons[field.iconName]}
LeftIcon={getIcon(field.iconName)}
iconButtons={getIconButtons(index + 1, field)}
isTooltipOpen={openToolTipIndex === index + 1}
text={field.label}
@ -126,7 +126,7 @@ export const ViewFieldsVisibilityDropdownSection = ({
fields.map((field, index) => (
<MenuItem
key={field.fieldMetadataId}
LeftIcon={icons[field.iconName]}
LeftIcon={getIcon(field.iconName)}
iconButtons={getIconButtons(index, field)}
isTooltipOpen={openToolTipIndex === index}
text={field.label}

View File

@ -1,16 +1,12 @@
import { getOperationName } from '@apollo/client/utilities';
import { Meta, StoryObj } from '@storybook/react';
import { within } from '@storybook/test';
import { graphql } from 'msw';
import { AppPath } from '@/types/AppPath';
import {
PageDecorator,
PageDecoratorArgs,
} from '~/testing/decorators/PageDecorator';
import { mockedOnboardingUsersData } from '~/testing/mock-data/users';
import { GET_CURRENT_USER } from '../../../modules/users/graphql/queries/getCurrentUser';
import { CreateProfile } from '../CreateProfile';
const meta: Meta<PageDecoratorArgs> = {
@ -18,20 +14,7 @@ const meta: Meta<PageDecoratorArgs> = {
component: CreateProfile,
decorators: [PageDecorator],
args: { routePath: AppPath.CreateProfile },
parameters: {
msw: [
graphql.query(
getOperationName(GET_CURRENT_USER) ?? '',
(req, res, ctx) => {
return res(
ctx.data({
currentUser: mockedOnboardingUsersData[1],
}),
);
},
),
],
},
parameters: {},
};
export default meta;

View File

@ -1,16 +1,12 @@
import { getOperationName } from '@apollo/client/utilities';
import { Meta, StoryObj } from '@storybook/react';
import { within } from '@storybook/test';
import { graphql } from 'msw';
import { AppPath } from '@/types/AppPath';
import {
PageDecorator,
PageDecoratorArgs,
} from '~/testing/decorators/PageDecorator';
import { mockedOnboardingUsersData } from '~/testing/mock-data/users';
import { GET_CURRENT_USER } from '../../../modules/users/graphql/queries/getCurrentUser';
import { CreateWorkspace } from '../CreateWorkspace';
const meta: Meta<PageDecoratorArgs> = {
@ -19,18 +15,7 @@ const meta: Meta<PageDecoratorArgs> = {
decorators: [PageDecorator],
args: { routePath: AppPath.CreateWorkspace },
parameters: {
msw: [
graphql.query(
getOperationName(GET_CURRENT_USER) ?? '',
(req, res, ctx) => {
return res(
ctx.data({
currentUser: mockedOnboardingUsersData[0],
}),
);
},
),
],
msw: [],
},
};

View File

@ -1,4 +1,4 @@
import { ThemeType } from './src/modules/ui/theme/constants/theme';
import { ThemeType } from './src/modules/ui/theme/constants/theme';
export {ThemeProvider} from '@emotion/react';