From e6b60759b81577bda6d75ac238bc2ff33fee0398 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Wed, 8 Jul 2026 17:48:47 -0700 Subject: [PATCH 1/2] feat(chat): replace thinking indicator with gooey loader Promotes ThinkingLoader from the landing route group to the shared components/ui barrel and swaps it in for the 4-square color loader in the chat's PendingTagIndicator. Removes the now-dead animate-thinking-block keyframe/animation. --- .../build-callout/build-callout.tsx | 2 +- .../build-chat-animation.tsx | 2 +- .../hero-chat-loop/hero-chat-loop.tsx | 2 +- .../components/hero-visual/hero-visual.tsx | 2 +- .../landing-preview-chat.tsx | 2 +- .../navbar/components/logo-mark/logo-mark.tsx | 2 +- .../components/thinking-loader/index.ts | 1 - .../components/special-tags/special-tags.tsx | 21 +++---------------- apps/sim/components/ui/index.ts | 1 + .../ui}/thinking-loader.module.css | 0 .../ui}/thinking-loader.tsx | 2 +- apps/sim/tailwind.config.ts | 5 ----- 12 files changed, 11 insertions(+), 31 deletions(-) delete mode 100644 apps/sim/app/(landing)/components/thinking-loader/index.ts rename apps/sim/{app/(landing)/components/thinking-loader => components/ui}/thinking-loader.module.css (100%) rename apps/sim/{app/(landing)/components/thinking-loader => components/ui}/thinking-loader.tsx (99%) diff --git a/apps/sim/app/(landing)/components/features/components/build-callout/build-callout.tsx b/apps/sim/app/(landing)/components/features/components/build-callout/build-callout.tsx index b6fab17e882..fe82b933240 100644 --- a/apps/sim/app/(landing)/components/features/components/build-callout/build-callout.tsx +++ b/apps/sim/app/(landing)/components/features/components/build-callout/build-callout.tsx @@ -1,5 +1,5 @@ +import { ThinkingLoader } from '@/components/ui' import { WorkflowShowcase } from '@/app/(landing)/components/features/components/build-callout/components/workflow-showcase' -import { ThinkingLoader } from '@/app/(landing)/components/thinking-loader' /** * The Build beat's callout - the finished workflow canvas centered on the diff --git a/apps/sim/app/(landing)/components/features/components/build-callout/components/build-chat-animation/build-chat-animation.tsx b/apps/sim/app/(landing)/components/features/components/build-callout/components/build-chat-animation/build-chat-animation.tsx index 1daf1d561c1..e005ab6de22 100644 --- a/apps/sim/app/(landing)/components/features/components/build-callout/components/build-chat-animation/build-chat-animation.tsx +++ b/apps/sim/app/(landing)/components/features/components/build-callout/components/build-chat-animation/build-chat-animation.tsx @@ -4,7 +4,7 @@ import { useEffect, useRef, useState } from 'react' import { cn } from '@sim/emcn' import { Blimp } from '@sim/emcn/icons' import { ArrowUp, Mic, Paperclip, Plus, Slash } from 'lucide-react' -import { ThinkingLoader } from '@/app/(landing)/components/thinking-loader' +import { ThinkingLoader } from '@/components/ui' const PROMPT = 'Build a workflow to schedule and publish posts to my X account.' const REPLY = diff --git a/apps/sim/app/(landing)/components/hero/components/hero-chat-loop/hero-chat-loop.tsx b/apps/sim/app/(landing)/components/hero/components/hero-chat-loop/hero-chat-loop.tsx index 1571acb9eef..8c37423abef 100644 --- a/apps/sim/app/(landing)/components/hero/components/hero-chat-loop/hero-chat-loop.tsx +++ b/apps/sim/app/(landing)/components/hero/components/hero-chat-loop/hero-chat-loop.tsx @@ -13,8 +13,8 @@ import { ThumbsDown, ThumbsUp, } from 'lucide-react' +import { ThinkingLoader } from '@/components/ui' import { HERO_TOOLTIP_OFFSET } from '@/app/(landing)/components/hero/components/hero-platform-loop/sidebar-hotspots' -import { ThinkingLoader } from '@/app/(landing)/components/thinking-loader' /** The conversation the loop plays - mirrors the seeded capture chat. */ const USER_MESSAGE = 'When a new lead signs up, enrich it with company data and post it to #sales.' diff --git a/apps/sim/app/(landing)/components/hero/components/hero-visual/hero-visual.tsx b/apps/sim/app/(landing)/components/hero/components/hero-visual/hero-visual.tsx index dde1aadba94..b163bf0672d 100644 --- a/apps/sim/app/(landing)/components/hero/components/hero-visual/hero-visual.tsx +++ b/apps/sim/app/(landing)/components/hero/components/hero-visual/hero-visual.tsx @@ -9,6 +9,7 @@ import { useState, } from 'react' import { cn } from '@sim/emcn' +import { ThinkingLoader } from '@/components/ui' import { BlockHandles } from '@/app/(landing)/components/hero/components/hero-visual/block-handles' import { type HomeMode, @@ -37,7 +38,6 @@ import { TYPE_MS_PER_ATOM, WORKFLOW_FOCUS_SCALE, } from '@/app/(landing)/components/hero/components/hero-visual/workflow-data' -import { ThinkingLoader } from '@/app/(landing)/components/thinking-loader' /** * Animated hero visual - the only client island in the hero, decorative and diff --git a/apps/sim/app/(landing)/components/landing-preview/components/landing-preview-chat/landing-preview-chat.tsx b/apps/sim/app/(landing)/components/landing-preview/components/landing-preview-chat/landing-preview-chat.tsx index 77d7ceb3a77..1a47f8b3a64 100644 --- a/apps/sim/app/(landing)/components/landing-preview/components/landing-preview-chat/landing-preview-chat.tsx +++ b/apps/sim/app/(landing)/components/landing-preview/components/landing-preview-chat/landing-preview-chat.tsx @@ -2,11 +2,11 @@ import { useEffect, useRef, useState } from 'react' import { cn } from '@sim/emcn' +import { ThinkingLoader } from '@/components/ui' import { LandingPreviewChatInput } from '@/app/(landing)/components/landing-preview/components/landing-preview-chat/chat-input' import { LandingPreviewChatTitleBar } from '@/app/(landing)/components/landing-preview/components/landing-preview-chat/chat-title-bar' import type { PreviewChat } from '@/app/(landing)/components/landing-preview/components/landing-preview-workflow/workflow-data' import { useLandingSubmit } from '@/app/(landing)/components/landing-preview/hooks/use-landing-submit' -import { ThinkingLoader } from '@/app/(landing)/components/thinking-loader' interface LandingPreviewChatProps { /** The scripted exchange to play, or `null` to show only the input. */ diff --git a/apps/sim/app/(landing)/components/navbar/components/logo-mark/logo-mark.tsx b/apps/sim/app/(landing)/components/navbar/components/logo-mark/logo-mark.tsx index d3d2f3165a0..039a5a793e6 100644 --- a/apps/sim/app/(landing)/components/navbar/components/logo-mark/logo-mark.tsx +++ b/apps/sim/app/(landing)/components/navbar/components/logo-mark/logo-mark.tsx @@ -2,7 +2,7 @@ import { type CSSProperties, type ReactNode, useState } from 'react' import { cn } from '@sim/emcn' -import { ThinkingLoader } from '@/app/(landing)/components/thinking-loader' +import { ThinkingLoader } from '@/components/ui' interface LogoMarkProps { /** Server-rendered Sim wordmark, shown by default. */ diff --git a/apps/sim/app/(landing)/components/thinking-loader/index.ts b/apps/sim/app/(landing)/components/thinking-loader/index.ts deleted file mode 100644 index c572ed1fc14..00000000000 --- a/apps/sim/app/(landing)/components/thinking-loader/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { ThinkingLoader, type ThinkingLoaderVariant } from './thinking-loader' 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 26dc28aad23..898f32f29ba 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 @@ -14,6 +14,7 @@ import { toast, } from '@sim/emcn' import { useParams } from 'next/navigation' +import { ThinkingLoader } from '@/components/ui' import { canonicalWorkspaceFilePath } from '@/lib/copilot/vfs/path-utils' import { isSafeHttpUrl } from '@/lib/core/utils/urls' import { OAUTH_PROVIDERS } from '@/lib/oauth/oauth' @@ -390,13 +391,6 @@ export function parseSpecialTags(content: string, isStreaming: boolean): ParsedS return { segments, hasPendingTag } } -const THINKING_BLOCKS = [ - { color: '#2ABBF8', delay: '0s' }, - { color: '#00F701', delay: '0.2s' }, - { color: '#FA4EDF', delay: '0.6s' }, - { color: '#FFCC02', delay: '0.4s' }, -] as const - interface SpecialTagsProps { segment: Exclude onOptionSelect?: (id: string) => void @@ -435,17 +429,8 @@ export function SpecialTags({ */ export function PendingTagIndicator() { return ( -
-
- {THINKING_BLOCKS.map((block, i) => ( -
- ))} -
- Thinking… +
+
) } diff --git a/apps/sim/components/ui/index.ts b/apps/sim/components/ui/index.ts index dfd0c105fb1..4ee1b9a7f0c 100644 --- a/apps/sim/components/ui/index.ts +++ b/apps/sim/components/ui/index.ts @@ -14,3 +14,4 @@ export { SelectTrigger, SelectValue, } from './select' +export { ThinkingLoader, type ThinkingLoaderVariant } from './thinking-loader' diff --git a/apps/sim/app/(landing)/components/thinking-loader/thinking-loader.module.css b/apps/sim/components/ui/thinking-loader.module.css similarity index 100% rename from apps/sim/app/(landing)/components/thinking-loader/thinking-loader.module.css rename to apps/sim/components/ui/thinking-loader.module.css diff --git a/apps/sim/app/(landing)/components/thinking-loader/thinking-loader.tsx b/apps/sim/components/ui/thinking-loader.tsx similarity index 99% rename from apps/sim/app/(landing)/components/thinking-loader/thinking-loader.tsx rename to apps/sim/components/ui/thinking-loader.tsx index 8db25b29402..700d39c9a56 100644 --- a/apps/sim/app/(landing)/components/thinking-loader/thinking-loader.tsx +++ b/apps/sim/components/ui/thinking-loader.tsx @@ -2,7 +2,7 @@ import { type CSSProperties, type ReactNode, useEffect, useId, useState } from 'react' import { cn } from '@sim/emcn' -import styles from '@/app/(landing)/components/thinking-loader/thinking-loader.module.css' +import styles from '@/components/ui/thinking-loader.module.css' const VARIANTS = [ 'metaballs', diff --git a/apps/sim/tailwind.config.ts b/apps/sim/tailwind.config.ts index 956ca1814b7..b8524763776 100644 --- a/apps/sim/tailwind.config.ts +++ b/apps/sim/tailwind.config.ts @@ -189,10 +189,6 @@ export default { from: { opacity: '0' }, to: { opacity: '1' }, }, - 'thinking-block': { - '0%, 100%': { opacity: '0.15' }, - '30%, 55%': { opacity: '1' }, - }, 'slide-in-right': { from: { transform: 'translateX(40px)' }, to: { transform: 'translateX(0)' }, @@ -251,7 +247,6 @@ export default { 'ring-pulse': 'ring-pulse 1.5s ease-in-out infinite', 'stream-fade-in': 'stream-fade-in 300ms ease-out forwards', 'stream-fade-in-delayed': 'stream-fade-in 300ms ease-out 1.5s forwards', - 'thinking-block': 'thinking-block 1.6s ease-in-out infinite', 'slide-in-right': 'slide-in-right 350ms ease-out forwards', 'slide-in-bottom': 'slide-in-bottom 400ms cubic-bezier(0.16, 1, 0.3, 1)', 'collapsible-down': 'collapsible-down 300ms cubic-bezier(0.4, 0, 0.2, 1)', From fc159a19ddd010ac249d9c3b035dd7af07b4bcc7 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Wed, 8 Jul 2026 17:54:57 -0700 Subject: [PATCH 2/2] =?UTF-8?q?fix(chat):=20keep=20a=20stable=20Thinking?= =?UTF-8?q?=E2=80=A6=20label=20instead=20of=20cycling=20phase=20text?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Greptile flagged that phase text repeatedly re-announces to assistive tech during a single pending stream; a static label avoids the repeated live-region updates while keeping the gooey shape morph. --- .../message-content/components/special-tags/special-tags.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 898f32f29ba..b303f7522bb 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 @@ -430,7 +430,7 @@ export function SpecialTags({ export function PendingTagIndicator() { return (
- +
) }