,
+ return useMemo(() => {
+ const defaults = getDefaults();
+ return {
+ ...defaults,
+ ...overrides,
+ // Deep-merge icons so user overrides layer over the full default map.
+ icons: { ...defaults.icons, ...overrides.icons },
+ } as ResolvedComponents;
// eslint-disable-next-line react-hooks/exhaustive-deps -- intentionally stable: overrides are set once at mount
- [],
- );
+ }, []);
};
diff --git a/package/src/contexts/componentsContext/defaultComponents.ts b/package/src/contexts/componentsContext/defaultComponents.ts
index b0aabf2bd6..2ac7a93a43 100644
--- a/package/src/contexts/componentsContext/defaultComponents.ts
+++ b/package/src/contexts/componentsContext/defaultComponents.ts
@@ -186,6 +186,90 @@ import { ChannelAvatar } from '../../components/ui/Avatar/ChannelAvatar';
import { SvgAwareImage } from '../../components/UIComponents/SvgAwareImage';
import { DefaultMessageOverlayBackground } from '../../contexts/overlayContext/MessageOverlayHostLayer';
import type { MessageActionsProps } from '../../contexts/overlayContext/MessageOverlayHostLayer';
+import { ArrowUp, Down } from '../../icons/arrow-up';
+import { ArrowUpRight } from '../../icons/arrow-up-right';
+import { Sound } from '../../icons/audio';
+import { Bell } from '../../icons/bell';
+import { Lightning } from '../../icons/bolt';
+import { Camera } from '../../icons/camera';
+import { Check, Tick } from '../../icons/checkmark';
+import { Checkmark } from '../../icons/checkmark-1';
+import { CheckAll } from '../../icons/checks';
+import { ChevronLeft } from '../../icons/chevron-left';
+import { ChevronRight } from '../../icons/chevron-right';
+import { ChevronUp } from '../../icons/chevron-up';
+import { Time } from '../../icons/clock';
+import { CommandsIcon } from '../../icons/command';
+import { Copy } from '../../icons/copy';
+import { Delete } from '../../icons/delete';
+import { Edit } from '../../icons/edit';
+import { Smile } from '../../icons/emoji';
+import { MoreEmojis } from '../../icons/emoji-add-1';
+import { ExclamationCircle } from '../../icons/exclamation-circle-fill';
+import { Exclamation } from '../../icons/exclamation-mark-fill';
+import { Warning } from '../../icons/exclamation-triangle-fill';
+import { EyeOpen } from '../../icons/EyeOpen';
+import { File, FilePickerIcon } from '../../icons/file';
+import { Audio } from '../../icons/filetype-audio-xl';
+import { Code } from '../../icons/filetype-code-xl';
+import { ZIP } from '../../icons/filetype-compression-xl';
+import { OtherFileIcon } from '../../icons/filetype-other-xl';
+import { PDF } from '../../icons/filetype-pdf-xl';
+import { Presentation } from '../../icons/filetype-presentation-xl';
+import { SpreadSheet } from '../../icons/filetype-spreadsheet-xl';
+import { DOC } from '../../icons/filetype-text-xl';
+import { Video } from '../../icons/filetype-video-xl';
+import { Flag, MessageFlag } from '../../icons/flag';
+import { Folder } from '../../icons/folder';
+import { ImageGrid } from '../../icons/gallery';
+import { Giphy as GiphyFiletypeIcon, GiphyIcon } from '../../icons/giphy';
+import { PhotoIcon, Picture } from '../../icons/image';
+import { Imgur } from '../../icons/imgur';
+import { InfoTooltip } from '../../icons/info';
+import { ArrowBoxLeft } from '../../icons/leave';
+import { Link } from '../../icons/link';
+import { Loading } from '../../icons/loading';
+import { MapPin } from '../../icons/location';
+import { Lock } from '../../icons/lock';
+import { Megaphone } from '../../icons/megaphone';
+import { MessageBubbleEmpty } from '../../icons/message-bubble';
+import { Minus } from '../../icons/minus';
+import { CircleMinus } from '../../icons/minus-circle';
+import { MenuPointHorizontal } from '../../icons/more';
+import { Mute } from '../../icons/mute';
+import { BlockUser, CircleBan } from '../../icons/no-sign';
+import { UnreadIndicator } from '../../icons/notification';
+import { Pause } from '../../icons/pause-fill';
+import { Pin } from '../../icons/pin';
+import { Play } from '../../icons/play-fill';
+import { Plus } from '../../icons/plus';
+import { PollIcon, PollThumbnail } from '../../icons/poll';
+import { Reload } from '../../icons/refresh';
+import { DotGrid } from '../../icons/reorder';
+import { ArrowShareLeft, CurveLineLeftUp } from '../../icons/reply';
+import { ReplyConnectorLeft } from '../../icons/ReplyConnectorLeft';
+import { ReplyConnectorRight } from '../../icons/ReplyConnectorRight';
+import { Resend } from '../../icons/Retry';
+import { Bookmark } from '../../icons/save';
+import { Search } from '../../icons/search';
+import { SendRight } from '../../icons/send';
+import { Share } from '../../icons/share';
+import { Shield } from '../../icons/shield';
+import { Stop } from '../../icons/stop-fill';
+import { ThreadReply } from '../../icons/thread';
+import { Unknown } from '../../icons/Unknown';
+import { Unlock } from '../../icons/unlock';
+import { Unpin } from '../../icons/unpin';
+import { UserAdd } from '../../icons/user-add';
+import { UserDelete } from '../../icons/user-remove';
+import { PeopleIcon } from '../../icons/users';
+import type { IconProps } from '../../icons/utils/base';
+import { VideoIcon } from '../../icons/video';
+import { Recorder } from '../../icons/video-fill';
+import { Mic } from '../../icons/voice';
+import { XCircle } from '../../icons/x-circle';
+import { NewClose } from '../../icons/xmark';
+import { Cross } from '../../icons/xmark-1';
/**
* Normalizes each component entry to React.ComponentType, stripping
@@ -197,7 +281,116 @@ type NormalizeComponents = {
[K in keyof T]: T[K] extends React.ComponentType ? React.ComponentType : T[K];
};
+/**
+ * All overridable icon components in the SDK, keyed by their exported name.
+ * Exposed via `WithComponents` under the nested `icons` key so integrators can
+ * swap any icon: ``.
+ *
+ * Only icons that are actually rendered by the SDK are registered here.
+ */
+export const defaultIcons = {
+ ArrowBoxLeft,
+ ArrowShareLeft,
+ ArrowUp,
+ ArrowUpRight,
+ Audio,
+ Bell,
+ BlockUser,
+ Bookmark,
+ Camera,
+ Check,
+ CheckAll,
+ Checkmark,
+ ChevronLeft,
+ ChevronRight,
+ ChevronUp,
+ CircleBan,
+ CircleMinus,
+ Code,
+ CommandsIcon,
+ Copy,
+ Cross,
+ CurveLineLeftUp,
+ Delete,
+ DOC,
+ DotGrid,
+ Down,
+ Edit,
+ Exclamation,
+ ExclamationCircle,
+ EyeOpen,
+ File,
+ FilePickerIcon,
+ Flag,
+ Folder,
+ Giphy: GiphyFiletypeIcon,
+ GiphyIcon,
+ ImageGrid,
+ Imgur,
+ InfoTooltip,
+ Lightning,
+ Link,
+ Loading,
+ Lock,
+ MapPin,
+ Megaphone,
+ MenuPointHorizontal,
+ MessageBubbleEmpty,
+ MessageFlag,
+ Mic,
+ Minus,
+ MoreEmojis,
+ Mute,
+ NewClose,
+ OtherFileIcon,
+ Pause,
+ PDF,
+ PeopleIcon,
+ PhotoIcon,
+ Picture,
+ Pin,
+ Play,
+ Plus,
+ PollIcon,
+ PollThumbnail,
+ Presentation,
+ Recorder,
+ Reload,
+ ReplyConnectorLeft,
+ ReplyConnectorRight,
+ Resend,
+ Search,
+ SendRight,
+ Share,
+ Shield,
+ Smile,
+ Sound,
+ SpreadSheet,
+ Stop,
+ ThreadReply,
+ Tick,
+ Time,
+ Unknown,
+ Unlock,
+ Unpin,
+ UnreadIndicator,
+ UserAdd,
+ UserDelete,
+ Video,
+ VideoIcon,
+ Warning,
+ XCircle,
+ ZIP,
+} satisfies Record>;
+
+/**
+ * Map of all overridable SDK icons. Used to type the `icons` override slot
+ * and the resolved value returned by `useComponentsContext().icons`.
+ */
+export type IconsMap = typeof defaultIcons;
+
const components = {
+ icons: defaultIcons,
Attachment,
AttachmentUploadIndicator,
AttachButton,
diff --git a/package/src/hooks/actions/__tests__/useChannelActionItems.test.tsx b/package/src/hooks/actions/__tests__/useChannelActionItems.test.tsx
index f3bb3d4c57..b77428c9f9 100644
--- a/package/src/hooks/actions/__tests__/useChannelActionItems.test.tsx
+++ b/package/src/hooks/actions/__tests__/useChannelActionItems.test.tsx
@@ -5,6 +5,7 @@ import type { Channel, Mute } from 'stream-chat';
import * as useMutedUsersModule from '../../../components/ChannelList/hooks/useMutedUsers';
import * as useIsChannelMutedModule from '../../../components/ChannelPreview/hooks/useIsChannelMuted';
+import { defaultIcons } from '../../../contexts/componentsContext/defaultComponents';
import type { TranslationContextValue } from '../../../contexts/translationContext/TranslationContext';
import * as TranslationContext from '../../../contexts/translationContext/TranslationContext';
import * as useChannelMembershipStateModule from '../../useChannelMembershipState';
@@ -219,6 +220,7 @@ describe('useChannelActionItems', () => {
isDirectChat: false,
isPinned: false,
surface: 'list',
+ icons: defaultIcons,
t: expect.any(Function),
userMuteActive: false,
},
@@ -246,6 +248,7 @@ describe('getChannelActionItems', () => {
isDirectChat: false,
isPinned: false,
surface: 'list',
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userMuteActive: false,
});
@@ -259,6 +262,7 @@ describe('getChannelActionItems', () => {
isDirectChat: false,
isPinned: false,
surface: 'list',
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userMuteActive: false,
},
@@ -291,6 +295,7 @@ describe('getChannelActionItems', () => {
isDirectChat: true,
isPinned: false,
surface: 'list',
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userMuteActive: true,
});
@@ -339,6 +344,7 @@ describe('getChannelActionItems', () => {
isDirectChat: false,
isPinned: false,
surface: 'list',
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userMuteActive: false,
});
@@ -356,6 +362,7 @@ describe('getChannelActionItems', () => {
isDirectChat: false,
isPinned: false,
surface: 'list',
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userMuteActive: false,
});
@@ -374,6 +381,7 @@ describe('getChannelActionItems', () => {
isDirectChat: false,
isPinned: false,
surface: 'list',
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userMuteActive: false,
});
@@ -399,6 +407,7 @@ describe('getChannelActionItems', () => {
isDirectChat: false,
isPinned: true,
surface: 'list',
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userMuteActive: false,
});
@@ -420,6 +429,7 @@ describe('getChannelActionItems', () => {
isDirectChat: true,
isPinned: false,
surface: 'list',
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userMuteActive: false,
});
@@ -439,6 +449,7 @@ describe('getChannelActionItems', () => {
isDirectChat: false,
isPinned: false,
surface: 'details',
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userMuteActive: false,
});
@@ -456,6 +467,7 @@ describe('getChannelActionItems', () => {
isDirectChat: false,
isPinned: false,
surface: 'list',
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userMuteActive: false,
});
@@ -472,6 +484,7 @@ describe('getChannelActionItems', () => {
isBlocked: undefined,
isDirectChat: false,
isPinned: false,
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userMuteActive: false,
});
@@ -490,6 +503,7 @@ describe('getChannelActionItems', () => {
isDirectChat: true,
isPinned: false,
surface: 'list',
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userMuteActive: true,
});
@@ -516,6 +530,7 @@ describe('getChannelActionItems', () => {
isDirectChat: false,
isPinned: false,
surface: 'list',
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userMuteActive: false,
});
diff --git a/package/src/hooks/actions/__tests__/useChannelMemberActionItems.test.tsx b/package/src/hooks/actions/__tests__/useChannelMemberActionItems.test.tsx
index aac6326a68..3a08164972 100644
--- a/package/src/hooks/actions/__tests__/useChannelMemberActionItems.test.tsx
+++ b/package/src/hooks/actions/__tests__/useChannelMemberActionItems.test.tsx
@@ -6,6 +6,7 @@ import type { Channel, ChannelMemberResponse, Mute } from 'stream-chat';
import * as useMutedUsersModule from '../../../components/ChannelList/hooks/useMutedUsers';
import { ChatProvider } from '../../../contexts/chatContext/ChatContext';
+import { defaultIcons } from '../../../contexts/componentsContext/defaultComponents';
import type { TranslationContextValue } from '../../../contexts/translationContext/TranslationContext';
import * as TranslationContext from '../../../contexts/translationContext/TranslationContext';
import * as useChannelOwnCapabilitiesModule from '../../useChannelOwnCapabilities';
@@ -227,6 +228,7 @@ describe('useChannelMemberActionItems', () => {
channelActions,
isBlocked: false,
isCurrentUser: false,
+ icons: defaultIcons,
member,
ownCapabilities: [],
t: expect.any(Function),
@@ -253,6 +255,7 @@ describe('buildDefaultChannelMemberActionItems', () => {
isCurrentUser: false,
member,
ownCapabilities: undefined,
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userActions: actions,
userMuteActive: false,
@@ -273,6 +276,7 @@ describe('buildDefaultChannelMemberActionItems', () => {
isCurrentUser: true,
member,
ownCapabilities: undefined,
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userActions: actions,
userMuteActive: false,
@@ -290,6 +294,7 @@ describe('buildDefaultChannelMemberActionItems', () => {
isCurrentUser: false,
member,
ownCapabilities: ['update-channel-members'],
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userActions: actions,
userMuteActive: false,
@@ -310,6 +315,7 @@ describe('buildDefaultChannelMemberActionItems', () => {
isCurrentUser: false,
member,
ownCapabilities: undefined,
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userActions: actions,
userMuteActive: true,
@@ -329,6 +335,7 @@ describe('buildDefaultChannelMemberActionItems', () => {
isCurrentUser: false,
member,
ownCapabilities: undefined,
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userActions: actions,
userMuteActive: true,
@@ -347,6 +354,7 @@ describe('buildDefaultChannelMemberActionItems', () => {
isCurrentUser: false,
member,
ownCapabilities: undefined,
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userActions: actions,
userMuteActive: false,
@@ -360,6 +368,7 @@ describe('buildDefaultChannelMemberActionItems', () => {
isCurrentUser: false,
member,
ownCapabilities: undefined,
+ icons: defaultIcons,
t: ((value: string) => value) as TranslationContextValue['t'],
userActions: actions,
userMuteActive: false,
diff --git a/package/src/hooks/actions/useChannelActionItems.tsx b/package/src/hooks/actions/useChannelActionItems.tsx
index 4f3a868eb0..04aed4012c 100644
--- a/package/src/hooks/actions/useChannelActionItems.tsx
+++ b/package/src/hooks/actions/useChannelActionItems.tsx
@@ -14,13 +14,28 @@ import {
import { useIsChannelMuted } from '../../components/ChannelPreview/hooks/useIsChannelMuted';
import { useUserMuteActive } from '../../components/Message/hooks/useUserMuteActive';
import { useTheme, useTranslationContext } from '../../contexts';
+import { useComponentsContext } from '../../contexts/componentsContext/ComponentsContext';
+import type { IconsMap } from '../../contexts/componentsContext/defaultComponents';
import type { TranslationContextValue } from '../../contexts/translationContext/TranslationContext';
-import { IconProps, Mute, BlockUser, Delete, Pin, Sound, Unpin } from '../../icons';
-import { ArrowBoxLeft } from '../../icons/leave';
+import { IconProps } from '../../icons';
import { useChannelMembershipState } from '../useChannelMembershipState';
import { useIsDirectChat } from '../useIsDirectChat';
import { useStateStore } from '../useStateStore';
+// Lazily resolved to avoid a static import cycle with defaultComponents.ts
+// (defaultComponents → ChannelDetails*/ChannelPreview* → this file). Statically
+// importing defaultIcons corrupts module-init order; require it at call time
+// instead. Same pattern as ComponentsContext's getDefaults().
+let cachedDefaultIcons: IconsMap | undefined;
+const getDefaultIcons = (): IconsMap => {
+ if (!cachedDefaultIcons) {
+ cachedDefaultIcons = (
+ require('../../contexts/componentsContext/defaultComponents') as { defaultIcons: IconsMap }
+ ).defaultIcons;
+ }
+ return cachedDefaultIcons;
+};
+
export type ChannelActionItem = ActionItem<
'mute' | 'muteUser' | 'block' | 'leave' | 'deleteChannel' | 'pin' | string
> & {
@@ -63,6 +78,7 @@ export type ChannelActionItemsParams = {
actions: ChannelActions;
channel: Channel;
channelMuteActive: boolean;
+ icons: IconsMap;
isArchived: boolean;
isBlocked: boolean | undefined;
isDirectChat: boolean;
@@ -73,7 +89,7 @@ export type ChannelActionItemsParams = {
};
export type BuildDefaultChannelActionItems = (
- channelActionItemsParams: ChannelActionItemsParams,
+ channelActionItemsParams: Omit & { icons?: IconsMap },
) => ChannelActionItem[];
const ChannelActionsIcon = ({
@@ -104,6 +120,7 @@ export const buildDefaultChannelActionItems: BuildDefaultChannelActionItems = (
unpin,
},
channelMuteActive,
+ icons = getDefaultIcons(),
isBlocked,
isDirectChat,
isPinned,
@@ -119,9 +136,9 @@ export const buildDefaultChannelActionItems: BuildDefaultChannelActionItems = (
action: channelMuteActive ? unmuteChannel : muteChannel,
Icon: (props) =>
channelMuteActive ? (
-
+
) : (
- ,
+ Icon: (props) => ,
id: 'pin',
label: isDirectChat
? isPinned
@@ -164,10 +181,10 @@ export const buildDefaultChannelActionItems: BuildDefaultChannelActionItems = (
action: userMuteActive ? unmuteUser : muteUser,
Icon: (props) =>
userMuteActive ? (
-
+
) : (
,
+ Icon: (props) => ,
id: 'block',
label: isBlocked ? t('Unblock User') : t('Block User'),
placement: 'sheet',
@@ -245,7 +262,7 @@ export const buildDefaultChannelActionItems: BuildDefaultChannelActionItems = (
actionItems.push({
action: leaveWithConfirmation,
- Icon: (props) => ,
+ Icon: (props) => ,
id: 'leave',
label: isDirectChat ? t('Leave Chat') : t('Leave Group'),
placement: 'sheet',
@@ -274,7 +291,7 @@ export const buildDefaultChannelActionItems: BuildDefaultChannelActionItems = (
},
]);
},
- Icon: (props) => ,
+ Icon: (props) => ,
id: 'deleteChannel',
label: isDirectChat ? t('Delete Chat') : t('Delete Group'),
placement: 'sheet',
@@ -307,6 +324,7 @@ export const useChannelActionItems = ({
getChannelActionItems: getChannelActionItemsProp = getChannelActionItems,
}: UseChannelActionItemsParams) => {
const { t } = useTranslationContext();
+ const { icons } = useComponentsContext();
const membership = useChannelMembershipState(channel);
const channelActions = useChannelActions(channel);
const isDirectChat = useIsDirectChat(channel);
@@ -331,6 +349,7 @@ export const useChannelActionItems = ({
actions: channelActions,
channel,
channelMuteActive,
+ icons,
isArchived,
isBlocked,
isDirectChat,
@@ -343,6 +362,7 @@ export const useChannelActionItems = ({
channel,
channelActions,
channelMuteActive,
+ icons,
isArchived,
isBlocked,
isDirectChat,
diff --git a/package/src/hooks/actions/useChannelMemberActionItems.tsx b/package/src/hooks/actions/useChannelMemberActionItems.tsx
index 25c056c550..d119d84ad8 100644
--- a/package/src/hooks/actions/useChannelMemberActionItems.tsx
+++ b/package/src/hooks/actions/useChannelMemberActionItems.tsx
@@ -9,16 +9,33 @@ import { useUserActions, UserActions } from './useUserActions';
import { useUserMuteActive } from '../../components/Message/hooks/useUserMuteActive';
import { useTheme, useTranslationContext } from '../../contexts';
+import { useComponentsContext } from '../../contexts/componentsContext/ComponentsContext';
+import type { IconsMap } from '../../contexts/componentsContext/defaultComponents';
import type { TranslationContextValue } from '../../contexts/translationContext/TranslationContext';
-import { BlockUser, IconProps, Mute, Sound, UserDelete } from '../../icons';
+import { IconProps } from '../../icons';
import { useChannelOwnCapabilities } from '../useChannelOwnCapabilities';
import { useStateStore } from '../useStateStore';
+// Lazily resolved to avoid a static import cycle with defaultComponents.ts
+// (defaultComponents → ChannelDetails*/ChannelPreview* → this file). Statically
+// importing defaultIcons corrupts module-init order; require it at call time
+// instead. Same pattern as ComponentsContext's getDefaults().
+let cachedDefaultIcons: IconsMap | undefined;
+const getDefaultIcons = (): IconsMap => {
+ if (!cachedDefaultIcons) {
+ cachedDefaultIcons = (
+ require('../../contexts/componentsContext/defaultComponents') as { defaultIcons: IconsMap }
+ ).defaultIcons;
+ }
+ return cachedDefaultIcons;
+};
+
export type ChannelMemberActionItem = ActionItem<'muteUser' | 'block' | string>;
export type ChannelMemberActionItemsParams = {
channel: Channel;
channelActions: ChannelActions;
+ icons: IconsMap;
isBlocked: boolean;
isCurrentUser: boolean;
member: ChannelMemberResponse;
@@ -29,7 +46,9 @@ export type ChannelMemberActionItemsParams = {
};
export type BuildDefaultChannelMemberActionItems = (
- channelMemberActionItemsParams: ChannelMemberActionItemsParams,
+ channelMemberActionItemsParams: Omit & {
+ icons?: IconsMap;
+ },
) => ChannelMemberActionItem[];
const ChannelMemberActionsIcon = ({
@@ -48,6 +67,7 @@ export const buildDefaultChannelMemberActionItems: BuildDefaultChannelMemberActi
) => {
const {
channelActions: { removeMembers },
+ icons = getDefaultIcons(),
isBlocked,
isCurrentUser,
member,
@@ -69,10 +89,10 @@ export const buildDefaultChannelMemberActionItems: BuildDefaultChannelMemberActi
action: userMuteActive ? unmuteUser : muteUser,
Icon: (props) =>
userMuteActive ? (
-
+
) : (
,
+ Icon: (props) => ,
id: 'block',
label: isBlocked ? t('Unblock User') : t('Block User'),
type: isBlocked ? 'standard' : 'destructive',
@@ -135,7 +155,7 @@ export const buildDefaultChannelMemberActionItems: BuildDefaultChannelMemberActi
],
);
},
- Icon: (props) => ,
+ Icon: (props) => ,
id: 'removeMember',
label: t('Remove User'),
type: 'destructive',
@@ -169,6 +189,7 @@ export const useChannelMemberActionItems = ({
getChannelMemberActionItems: getChannelMemberActionItemsProp = getChannelMemberActionItems,
}: UseChannelMemberActionItemsParams) => {
const { t } = useTranslationContext();
+ const { icons } = useComponentsContext();
const userActions = useUserActions(member.user);
const channelActions = useChannelActions(channel);
@@ -189,6 +210,7 @@ export const useChannelMemberActionItems = ({
() => ({
channel,
channelActions,
+ icons,
isBlocked,
isCurrentUser,
member,
@@ -200,6 +222,7 @@ export const useChannelMemberActionItems = ({
[
channel,
channelActions,
+ icons,
isBlocked,
isCurrentUser,
member,
diff --git a/package/src/hooks/messagePreview/useMessagePreviewIcon.tsx b/package/src/hooks/messagePreview/useMessagePreviewIcon.tsx
index 3136cc8f07..7ee95d5152 100644
--- a/package/src/hooks/messagePreview/useMessagePreviewIcon.tsx
+++ b/package/src/hooks/messagePreview/useMessagePreviewIcon.tsx
@@ -1,15 +1,8 @@
import { DraftMessage, LocalMessage, MessageResponse } from 'stream-chat';
+import { useComponentsContext } from '../../contexts/componentsContext/ComponentsContext';
import { useGroupedAttachments } from '../../hooks/messagePreview/useGroupedAttachments';
-import { File } from '../../icons/file';
-import { PhotoIcon } from '../../icons/image';
-import { Link } from '../../icons/link';
-import { MapPin } from '../../icons/location';
-import { CircleBan } from '../../icons/no-sign';
-import { PollIcon } from '../../icons/poll';
-import { VideoIcon } from '../../icons/video';
-import { Mic } from '../../icons/voice';
import { FileTypes } from '../../types/types';
export const useMessagePreviewIcon = ({
@@ -17,6 +10,7 @@ export const useMessagePreviewIcon = ({
}: {
message?: LocalMessage | MessageResponse | DraftMessage | null;
}) => {
+ const { icons } = useComponentsContext();
const { giphys, audios, images, videos, files, voiceRecordings } = useGroupedAttachments(
message?.attachments,
);
@@ -36,39 +30,39 @@ export const useMessagePreviewIcon = ({
);
if (message.type === 'deleted') {
- return CircleBan;
+ return icons.CircleBan;
}
if (message.poll_id) {
- return PollIcon;
+ return icons.PollIcon;
}
if (message.shared_location) {
- return MapPin;
+ return icons.MapPin;
}
if (hasLink) {
- return Link;
+ return icons.Link;
}
if (onlyAudio || onlyVoiceRecordings) {
- return Mic;
+ return icons.Mic;
}
if (onlyVideos) {
- return VideoIcon;
+ return icons.VideoIcon;
}
if (onlyImages) {
- return PhotoIcon;
+ return icons.PhotoIcon;
}
if (giphys?.length) {
- return File;
+ return icons.File;
}
if (files?.length || images?.length || videos?.length || audios?.length) {
- return File;
+ return icons.File;
}
return null;
diff --git a/package/src/icons/arrow-left.tsx b/package/src/icons/arrow-left.tsx
deleted file mode 100644
index e39d201a97..0000000000
--- a/package/src/icons/arrow-left.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import React from 'react';
-import { I18nManager } from 'react-native';
-import Svg, { Path } from 'react-native-svg';
-
-import { IconProps } from './utils/base';
-
-export const ArrowLeft = ({ height, size, style, width, ...rest }: IconProps) => (
-
-);