From 0e00cb809d0db8d1b00f0472bb585f63f64ad7f9 Mon Sep 17 00:00:00 2001 From: Bill Leoutsakos Date: Sat, 19 Sep 2026 11:07:06 -0700 Subject: [PATCH 1/2] refactor(ui): reuse EMCN icons for simple product glyphs --- .../components/agent-group/index.ts | 1 - .../components/agent-group/tool-call-item.tsx | 16 ---------- .../message-content/components/index.ts | 2 +- .../components/special-tags/special-tags.tsx | 31 ++++++------------- .../message-content-overlay.test.tsx | 1 - .../message-content/message-content.tsx | 10 ++---- .../comparison-table/comparison-table.tsx | 27 ++-------------- .../components/tag-dropdown/tag-dropdown.tsx | 10 ++---- .../variables-input/variables-input.tsx | 16 ++-------- packages/emcn/src/icons/circle-stop.tsx | 22 +++++++++++++ packages/emcn/src/icons/index.ts | 1 + 11 files changed, 42 insertions(+), 95 deletions(-) create mode 100644 packages/emcn/src/icons/circle-stop.tsx diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/index.ts b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/index.ts index 7f8d6ef3cdd..0e87649b7f8 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/index.ts +++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/index.ts @@ -4,4 +4,3 @@ export type { NestedAgentGroup, } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group-view' export { isAgentGroupResolved } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group-view' -export { CircleStop } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item' diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx index 7d2bec15dd5..886243b9584 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx @@ -26,22 +26,6 @@ import { BrandIcon } from '@/blocks/brand-icon' import { useCustomBlockOverlayVersion } from '@/blocks/custom/client-overlay' import { getBlockByToolName } from '@/blocks/registry' -export function CircleStop({ className }: { className?: string }) { - return ( - - - - - ) -} - export interface ToolCallItemProps { toolName: string displayTitle: string diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/index.ts b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/index.ts index 07f0139dc83..0bbe8af07fb 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/index.ts +++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/index.ts @@ -1,5 +1,5 @@ export type { AgentGroupItem, NestedAgentGroup } from './agent-group' -export { AgentGroup, CircleStop, isAgentGroupResolved } from './agent-group' +export { AgentGroup, isAgentGroupResolved } from './agent-group' export { ChatContent } from './chat-content' export { MessageSources } from './message-sources' export { Options } from './options' diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.tsx index c96110df49f..ef6f90f8e37 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.tsx @@ -2,7 +2,14 @@ import { lazy, Suspense, useCallback, useEffect, useMemo, useState } from 'react' import { cn, Expandable, ExpandableContent, SecretReveal, Tooltip, toast } from '@sim/emcn' -import { ArrowRight, Check, ChevronDown, SquareArrowUpRight, TerminalWindow } from '@sim/emcn/icons' +import { + ArrowRight, + Check, + ChevronDown, + Lock, + SquareArrowUpRight, + TerminalWindow, +} from '@sim/emcn/icons' import { isRecordLike } from '@sim/utils/object' import { useParams } from 'next/navigation' import { useSession } from '@/lib/auth/auth-client' @@ -1986,24 +1993,6 @@ function getCredentialProviderDisplayName(provider: string): string { ) } -const LockIcon = (props: { className?: string }) => ( - - - - - -) - /** * Inline "paste a secret" widget rendered for * `{"type":"secret_input","name":"OPENAI_API_KEY"}`. @@ -2484,7 +2473,7 @@ function CredentialLinkDisplay({ // The connect link value comes from the streamed model output, so only // render it as a clickable link when it resolves to a real http(s) URL. if (!data.value || !isSafeHttpUrl(data.value)) return null - const Icon = getCredentialIcon(data.provider) ?? LockIcon + const Icon = getCredentialIcon(data.provider) ?? Lock const label = reconnectCredentialId ? `Reconnect ${reconnectCredential?.displayName ?? integrationName}` : hasExistingCredential @@ -2550,7 +2539,7 @@ function PersonalCredentialLinkDisplay({ onConnected, }) if (!provider || (provider.toLowerCase() === 'gitlab' && !canEdit)) return null - const Icon = getCredentialIcon(provider) ?? LockIcon + const Icon = getCredentialIcon(provider) ?? Lock const connected = connection.status === 'connected' const label = connected ? `Connected ${name}` diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content-overlay.test.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content-overlay.test.tsx index 4228bb4093b..194adc9162c 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content-overlay.test.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content-overlay.test.tsx @@ -31,7 +31,6 @@ vi.mock('./components', () => ({ ), ChatContent: () => null, - CircleStop: () => null, Options: () => null, PendingTagIndicator: () => null, })) diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content.tsx index da219a9ff30..fdd9ed5c7ee 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content.tsx @@ -11,6 +11,7 @@ import { useState, } from 'react' import { cn } from '@sim/emcn' +import { CircleStop } from '@sim/emcn/icons' import { PrepareFileEdit, Read as ReadTool } from '@/lib/copilot/generated/tool-catalog-v1' import { isToolHiddenInUi } from '@/lib/copilot/tools/client/hidden-tools' import { resolveToolDisplay } from '@/lib/copilot/tools/client/store-utils' @@ -40,14 +41,7 @@ import type { import { SUBAGENT_LABELS } from '@/app/workspace/[workspaceId]/home/types' import { useCustomBlockOverlayVersion } from '@/blocks/custom/client-overlay' import type { AgentGroupItem } from './components' -import { - AgentGroup, - ChatContent, - CircleStop, - MessageSources, - Options, - PendingTagIndicator, -} from './components' +import { AgentGroup, ChatContent, MessageSources, Options, PendingTagIndicator } from './components' import { deriveMessagePhase, isToolDone, type MessagePhase } from './utils' const FILE_SUBAGENT_ID = 'file' diff --git a/apps/sim/app/workspace/[workspaceId]/upgrade/components/comparison-table/comparison-table.tsx b/apps/sim/app/workspace/[workspaceId]/upgrade/components/comparison-table/comparison-table.tsx index 34a7736a273..980886ce5ff 100644 --- a/apps/sim/app/workspace/[workspaceId]/upgrade/components/comparison-table/comparison-table.tsx +++ b/apps/sim/app/workspace/[workspaceId]/upgrade/components/comparison-table/comparison-table.tsx @@ -1,5 +1,6 @@ 'use client' import { chipVariants, cn } from '@sim/emcn' +import { Check } from '@sim/emcn/icons' import { SlackIcon } from '@/components/icons' import { BillingPeriodToggle } from '@/app/workspace/[workspaceId]/upgrade/components/billing-period-toggle/billing-period-toggle' import { @@ -54,30 +55,6 @@ export interface ComparisonTableProps { ctas: Partial> } -/** - * Inline check icon — matches the card-level `CheckIcon` shape. - */ -function CheckIcon() { - return ( - - ) -} - /** * Renders a single cell value: `true` → check icon, `false` → em-dash, string → text. */ @@ -85,7 +62,7 @@ function Cell({ value }: { value: CellValue }) { if (value === true) { return ( - + ) } diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tag-dropdown/tag-dropdown.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tag-dropdown/tag-dropdown.tsx index 4e1c2f9f0e6..bb2c7d8d14f 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tag-dropdown/tag-dropdown.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tag-dropdown/tag-dropdown.tsx @@ -12,6 +12,7 @@ import { PopoverSection, usePopoverContext, } from '@sim/emcn' +import { ChevronLeft } from '@sim/emcn/icons' import { getEffectiveBlockOutputType, getOutputPathsFromSchema, @@ -862,14 +863,7 @@ const TagDropdownBackButton: React.FC<{ setSelectedIndex: (index: number) => voi }} onMouseEnter={handleMouseEnter} > - - - + Back ) diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/variables-input/variables-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/variables-input/variables-input.tsx index 5301bf26a18..bb9352bef92 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/variables-input/variables-input.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/variables-input/variables-input.tsx @@ -11,7 +11,7 @@ import { Textarea, Tooltip, } from '@sim/emcn' -import { ArrowLeftRight, Plus, Trash } from '@sim/emcn/icons' +import { ArrowLeftRight, FileText, Plus, Trash } from '@sim/emcn/icons' import { generateId } from '@sim/utils/id' import { useParams } from 'next/navigation' import { formatDisplayText } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/formatted-text' @@ -336,19 +336,7 @@ export function VariablesInput({ if (isPreview && (!assignments || assignments.length === 0)) { return (
- - - +

No variable assignments defined

Add variables in the Variables panel to get started diff --git a/packages/emcn/src/icons/circle-stop.tsx b/packages/emcn/src/icons/circle-stop.tsx new file mode 100644 index 00000000000..283c6f9ffb7 --- /dev/null +++ b/packages/emcn/src/icons/circle-stop.tsx @@ -0,0 +1,22 @@ +import type { SVGProps } from 'react' + +/** + * Circled stop icon for stopped activity. + * @param props - SVG properties including className and accessibility attributes. + */ +export function CircleStop(props: SVGProps) { + return ( + + ) +} diff --git a/packages/emcn/src/icons/index.ts b/packages/emcn/src/icons/index.ts index 568ea9c495a..6c95ca5aae9 100644 --- a/packages/emcn/src/icons/index.ts +++ b/packages/emcn/src/icons/index.ts @@ -37,6 +37,7 @@ export { CircleAlert } from './circle-alert' export { CircleCheck } from './circle-check' export { CircleInfo } from './circle-info' export { CirclePause } from './circle-pause' +export { CircleStop } from './circle-stop' export { CircleX } from './circle-x' export { Clipboard } from './clipboard' export { ClipboardList } from './clipboard-list' From fb2589f872d5387671c96d377c4aad81bc8bfe03 Mon Sep 17 00:00:00 2001 From: Bill Leoutsakos Date: Sat, 19 Sep 2026 11:48:25 -0700 Subject: [PATCH 2/2] docs(emcn): add CircleStop usage example --- packages/emcn/src/icons/circle-stop.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/emcn/src/icons/circle-stop.tsx b/packages/emcn/src/icons/circle-stop.tsx index 283c6f9ffb7..21947338ccc 100644 --- a/packages/emcn/src/icons/circle-stop.tsx +++ b/packages/emcn/src/icons/circle-stop.tsx @@ -3,6 +3,10 @@ import type { SVGProps } from 'react' /** * Circled stop icon for stopped activity. * @param props - SVG properties including className and accessibility attributes. + * @example + * import { CircleStop } from '@sim/emcn/icons' + * + * */ export function CircleStop(props: SVGProps) { return (