Skip to content

Commit cc48256

Browse files
committed
fix(integrations): render one brand icon state everywhere
A service glyph was drawn three different ways depending on the surface: brand-colored via getBareIconStyle, muted through --text-icon, or left to inherit the surrounding text color. The same Dropbox icon therefore read blue in suggested actions and grey in the connect modal. Replace the loose helper with a single BrandIcon component (plus withBrandIcon for component-shaped icon slots) that owns the color, and migrate every bare call site to it. The tiled treatment (BlockTile / IntegrationTile) is unchanged.
1 parent 04e0fe0 commit cc48256

20 files changed

Lines changed: 176 additions & 100 deletions

File tree

apps/sim/app/workspace/[workspaceId]/components/connect-oauth-modal/connect-oauth-modal.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
parseProvider,
2727
} from '@/lib/oauth'
2828
import { getScopeDescription, getServiceConfigByProviderId } from '@/lib/oauth/utils'
29+
import { withBrandIcon } from '@/blocks/brand-icon'
2930
import { useCreateCredentialDraft, useWorkspaceCredentials } from '@/hooks/queries/credentials'
3031
import { useConnectOAuthService } from '@/hooks/queries/oauth/oauth-connections'
3132

@@ -49,11 +50,11 @@ function isHiddenScope(scope: string): boolean {
4950
function resolveService(
5051
provider: OAuthProvider,
5152
serviceId: string
52-
): { providerName: string; ProviderIcon: ServiceIcon } {
53+
): { providerName: string; ProviderIcon: ServiceIcon | null } {
5354
const { baseProvider } = parseProvider(provider)
5455
const baseProviderConfig = OAUTH_PROVIDERS[baseProvider]
5556
let providerName = baseProviderConfig?.name || provider
56-
let ProviderIcon: ServiceIcon = baseProviderConfig?.icon || (() => null)
57+
let ProviderIcon: ServiceIcon | null = baseProviderConfig?.icon ?? null
5758
if (baseProviderConfig) {
5859
for (const [key, service] of Object.entries(baseProviderConfig.services)) {
5960
if (key === serviceId || service.providerId === provider) {
@@ -355,7 +356,10 @@ export function ConnectOAuthModal(props: ConnectOAuthModalProps) {
355356

356357
return (
357358
<ChipModal open={open} onOpenChange={onOpenChange} srTitle={title}>
358-
<ChipModalHeader icon={ProviderIcon} onClose={handleClose}>
359+
<ChipModalHeader
360+
icon={ProviderIcon ? withBrandIcon(ProviderIcon) : null}
361+
onClose={handleClose}
362+
>
359363
{title}
360364
</ChipModalHeader>
361365
<ChipModalBody>

apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/mention/mention-chip.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { cn } from '@sim/emcn'
33
import type { ReactNodeViewProps } from '@tiptap/react'
44
import { NodeViewWrapper, ReactNodeViewRenderer } from '@tiptap/react'
55
import { useParams, useRouter } from 'next/navigation'
6-
import { getBareIconStyle, type StyleableIcon } from '@/blocks/brand-icon-style'
6+
import { BrandIcon, type StyleableIcon } from '@/blocks/brand-icon'
77
import { mentionIcon } from './mention-icon'
88
import { MarkdownMention, type MentionAttrs } from './mention-node'
99
import { simLinkPath } from './sim-link'
@@ -13,8 +13,8 @@ import { simLinkPath } from './sim-link'
1313
* in `prompt-editor.tsx`): a borderless inline icon + label that flows with the
1414
* surrounding prose — no pill background, no padding, normal weight, body text
1515
* color, and a 12px icon. Integration icons keep their brand color via
16-
* {@link getBareIconStyle} (see {@link MentionChipView}); other kinds stay
17-
* monochrome through the `--text-icon` fallback below.
16+
* {@link BrandIcon} (see {@link MentionChipView}); other kinds stay
17+
* monochrome through its `--text-icon` fallback.
1818
*
1919
* No explicit label color — an element's own explicit `color` always wins over an inherited one
2020
* regardless of ancestor specificity, so hardcoding `--text-primary` here (redundant with the prose
@@ -24,7 +24,7 @@ import { simLinkPath } from './sim-link'
2424
* in rich-markdown-editor.css.
2525
*/
2626
const CHIP_CLASS =
27-
'mention-chip mx-px inline-flex items-center gap-1 align-middle leading-[1.5] [&>svg]:size-[12px] [&>svg]:shrink-0 [&>svg]:text-[var(--text-icon)]'
27+
'mention-chip mx-px inline-flex items-center gap-1 align-middle leading-[1.5] [&>svg]:size-[12px] [&>svg]:shrink-0'
2828

2929
/**
3030
* Live chip: an entity icon + label matching the chat input's mention rendering. Where the host opted
@@ -37,7 +37,6 @@ export function MentionChipView({ node, editor }: ReactNodeViewProps) {
3737
const params = useParams()
3838
const { kind, id, label } = node.attrs as MentionAttrs
3939
const Icon = mentionIcon(kind, id, label) as StyleableIcon | undefined
40-
const iconStyle = Icon ? getBareIconStyle(Icon) : undefined
4140
const navigable = editor.storage.mentionMenu?.navigable === true
4241
const workspaceId = typeof params.workspaceId === 'string' ? params.workspaceId : undefined
4342
const path = navigable && workspaceId ? simLinkPath(workspaceId, kind, id) : null
@@ -55,7 +54,7 @@ export function MentionChipView({ node, editor }: ReactNodeViewProps) {
5554
onClick={path ? handleClick : undefined}
5655
title={label}
5756
>
58-
{Icon && <Icon style={iconStyle} />}
57+
{Icon && <BrandIcon icon={Icon} />}
5958
<span>{label}</span>
6059
</NodeViewWrapper>
6160
)

apps/sim/app/workspace/[workspaceId]/home/components/chat-context-kind-registry/chat-context-kind-registry.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
import { AgentSkillsIcon, McpIcon } from '@/components/icons'
1313
import { getDocumentIcon } from '@/components/icons/document-icons'
1414
import type { ChatContextKind, ChatMessageContext } from '@/app/workspace/[workspaceId]/home/types'
15-
import { getBareIconStyle } from '@/blocks/brand-icon-style'
15+
import { BrandIcon } from '@/blocks/brand-icon'
1616
import { getBlockRegistry } from '@/blocks/registry'
1717

1818
interface RenderIconArgs {
@@ -42,8 +42,7 @@ function renderIntegrationTile({ context, className }: RenderIconArgs): ReactNod
4242
if (!context.blockType) return null
4343
const block = getBlockRegistry()[context.blockType]
4444
if (!block) return null
45-
const Icon = block.icon
46-
return <Icon className={className} style={getBareIconStyle(Icon)} />
45+
return <BrandIcon icon={block.icon} className={className} />
4746
}
4847

4948
/**

apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
import { getReadTargetBlock } from '@/lib/copilot/tools/client/read-block'
1313
import { extractStreamingStringArgument } from '@/lib/copilot/tools/streaming-args'
1414
import { getToolStatusDisplayTitle, getWaitCountdownTitle } from '@/lib/copilot/tools/tool-display'
15-
import { getBareIconStyle } from '@/blocks/brand-icon-style'
15+
import { BrandIcon } from '@/blocks/brand-icon'
1616
import { getBlockByToolName } from '@/blocks/registry'
1717
import type { ToolCallData, ToolCallStatus } from '../../../../types'
1818
import { resolveToolDisplayState } from '../../utils'
@@ -237,12 +237,7 @@ export function ToolCallItem({
237237

238238
return (
239239
<div className='flex items-center gap-[6px] pl-6'>
240-
{BlockIcon && (
241-
<BlockIcon
242-
className='size-[14px] flex-shrink-0 text-[var(--text-icon)]'
243-
style={getBareIconStyle(BlockIcon)}
244-
/>
245-
)}
240+
{BlockIcon && <BrandIcon icon={BlockIcon} className='size-[14px] flex-shrink-0' />}
246241
{isExecuting ? (
247242
<ShimmerText className='text-[13px] [--shimmer-rest:var(--text-secondary)]'>
248243
{title}

apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client'
22

3-
import { createElement, lazy, Suspense, useCallback, useEffect, useMemo, useState } from 'react'
3+
import { lazy, Suspense, useCallback, useEffect, useMemo, useState } from 'react'
44
import {
55
ArrowRight,
66
Check,
@@ -61,6 +61,7 @@ import type {
6161
import { useServiceAccountConnectTarget } from '@/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal/use-service-account-connect'
6262
import { useWorkspaceHostContext } from '@/app/workspace/[workspaceId]/providers/workspace-host-provider'
6363
import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider'
64+
import { BrandIcon } from '@/blocks/brand-icon'
6465
import {
6566
useUpdateWorkspaceCredential,
6667
useWorkspaceCredential,
@@ -2160,7 +2161,7 @@ function ServiceAccountConnectDisplay({
21602161
'hover-hover:bg-[var(--surface-5)]'
21612162
)}
21622163
>
2163-
{createElement(target.serviceIcon, { className: 'size-[16px] shrink-0' })}
2164+
<BrandIcon icon={target.serviceIcon} className='size-[16px] shrink-0' />
21642165
<span className='flex-1 text-[var(--text-body)] text-sm'>{displayLabel}</span>
21652166
{connected ? (
21662167
<Check className='size-[16px] shrink-0 text-[var(--text-icon)]' />
@@ -2257,7 +2258,7 @@ function CredentialLinkDisplay({
22572258
'hover-hover:bg-[var(--surface-5)]'
22582259
)}
22592260
>
2260-
{createElement(Icon, { className: 'size-[16px] shrink-0' })}
2261+
<BrandIcon icon={Icon} className='size-[16px] shrink-0' />
22612262
<span className='flex-1 text-[var(--text-body)] text-sm'>{displayLabel}</span>
22622263
{connected ? (
22632264
<Check className='size-[16px] shrink-0 text-[var(--text-icon)]' />

apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-registry/resource-registry.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import type {
2020
MothershipResource,
2121
MothershipResourceType,
2222
} from '@/app/workspace/[workspaceId]/home/types'
23-
import { getBareIconStyle, type StyleableIcon } from '@/blocks/brand-icon-style'
23+
import { BrandIcon, type StyleableIcon } from '@/blocks/brand-icon'
2424
import { logKeys } from '@/hooks/queries/logs'
2525
import { mothershipChatKeys } from '@/hooks/queries/mothership-chats'
2626
import { folderKeys } from '@/hooks/queries/utils/folder-keys'
@@ -85,10 +85,7 @@ function IntegrationDropdownItem({ item }: DropdownItemRenderProps) {
8585
if (!Icon) return <span className='truncate'>{item.name}</span>
8686
return (
8787
<>
88-
<Icon
89-
className='size-[14px] flex-shrink-0 text-[var(--text-icon)]'
90-
style={getBareIconStyle(Icon)}
91-
/>
88+
<BrandIcon icon={Icon} className='size-[14px] flex-shrink-0' />
9289
<span className='truncate'>{item.name}</span>
9390
</>
9491
)

apps/sim/app/workspace/[workspaceId]/home/components/suggested-actions/suggested-actions.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
} from '@/lib/integrations'
1717
import { captureEvent } from '@/lib/posthog/client'
1818
import { ConnectOAuthModal } from '@/app/workspace/[workspaceId]/components/connect-oauth-modal'
19-
import { getBareIconStyle } from '@/blocks/brand-icon-style'
19+
import { BrandIcon } from '@/blocks/brand-icon'
2020
import { getAllBlockMeta } from '@/blocks/registry'
2121
import type { ModuleTag } from '@/blocks/types'
2222
import { useWorkspaceCredentials } from '@/hooks/queries/credentials'
@@ -389,10 +389,7 @@ export function SuggestedActions({ onSelectPrompt }: SuggestedActionsProps) {
389389
i > 0 && 'border-t'
390390
)}
391391
>
392-
<Icon
393-
className='size-[16px] flex-shrink-0 text-[var(--text-icon)]'
394-
style={getBareIconStyle(Icon)}
395-
/>
392+
<BrandIcon icon={Icon} className='size-[16px] flex-shrink-0' />
396393
<span className='flex-1 truncate text-[var(--text-body)] text-sm'>
397394
{action.label}
398395
</span>

apps/sim/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal/client-credential-account-modal.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
type ClientCredentialAccountFieldId,
2121
partitionClientCredentialFields,
2222
} from '@/lib/credentials/client-credential-accounts/descriptors'
23+
import { withBrandIcon } from '@/blocks/brand-icon'
2324
import {
2425
useCreateWorkspaceCredential,
2526
useUpdateWorkspaceCredential,
@@ -214,7 +215,7 @@ export function ClientCredentialAccountModal({
214215
onOpenChange={onOpenChange}
215216
srTitle={`Add ${serviceName} ${descriptor.connectNoun}`}
216217
>
217-
<ChipModalHeader icon={ServiceIcon} onClose={() => onOpenChange(false)}>
218+
<ChipModalHeader icon={withBrandIcon(ServiceIcon)} onClose={() => onOpenChange(false)}>
218219
Add {serviceName} {descriptor.connectNoun}
219220
</ChipModalHeader>
220221
<ChipModalBody>

apps/sim/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal/connect-service-account-modal.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
import { ClientCredentialAccountModal } from '@/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal/client-credential-account-modal'
3131
import { TokenServiceAccountModal } from '@/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal/token-service-account-modal'
3232
import { ConnectSlackBotModal } from '@/app/workspace/[workspaceId]/integrations/components/connect-slack-bot-modal/connect-slack-bot-modal'
33+
import { withBrandIcon } from '@/blocks/brand-icon'
3334
import {
3435
useCreateWorkspaceCredential,
3536
useUpdateWorkspaceCredential,
@@ -360,7 +361,7 @@ function GoogleServiceAccountModal({
360361
onOpenChange={onOpenChange}
361362
srTitle={`Add ${serviceName} service account`}
362363
>
363-
<ChipModalHeader icon={ServiceIcon} onClose={() => onOpenChange(false)}>
364+
<ChipModalHeader icon={withBrandIcon(ServiceIcon)} onClose={() => onOpenChange(false)}>
364365
Add {serviceName} service account
365366
</ChipModalHeader>
366367
<ChipModalBody>
@@ -512,7 +513,7 @@ function AtlassianServiceAccountModal({
512513
onOpenChange={onOpenChange}
513514
srTitle={`Add ${serviceName} service account`}
514515
>
515-
<ChipModalHeader icon={ServiceIcon} onClose={() => onOpenChange(false)}>
516+
<ChipModalHeader icon={withBrandIcon(ServiceIcon)} onClose={() => onOpenChange(false)}>
516517
Add {serviceName} service account
517518
</ChipModalHeader>
518519
<ChipModalBody>

apps/sim/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal/token-service-account-modal.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
type TokenServiceAccountDescriptor,
1818
type TokenServiceAccountField,
1919
} from '@/lib/credentials/token-service-accounts/descriptors'
20+
import { withBrandIcon } from '@/blocks/brand-icon'
2021
import {
2122
useCreateWorkspaceCredential,
2223
useUpdateWorkspaceCredential,
@@ -141,7 +142,7 @@ export function TokenServiceAccountModal({
141142
onOpenChange={onOpenChange}
142143
srTitle={`Add ${serviceName} ${descriptor.connectNoun}`}
143144
>
144-
<ChipModalHeader icon={ServiceIcon} onClose={() => onOpenChange(false)}>
145+
<ChipModalHeader icon={withBrandIcon(ServiceIcon)} onClose={() => onOpenChange(false)}>
145146
Add {serviceName} {descriptor.connectNoun}
146147
</ChipModalHeader>
147148
<ChipModalBody>

0 commit comments

Comments
 (0)