Skip to content

✨ Replace WebChat v2 With v3 on Main Branch#100

Open
cristiantela wants to merge 193 commits intomainfrom
v3-main
Open

✨ Replace WebChat v2 With v3 on Main Branch#100
cristiantela wants to merge 193 commits intomainfrom
v3-main

Conversation

@cristiantela
Copy link
Copy Markdown
Collaborator

Description

Type of Change

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Tests
  • Other

Motivation and Context

Version 2 of the WebChat widget has been deprecated. This pull request promotes the v3-main branch as the new baseline for main. The v2 codebase will remain available and maintainable under the v2-main branch for any critical hotfixes that may be required.

Summary of Changes

The key changes introduced by v3 include:

UI Redesign

  • Fully redesigned InputBox with updated styles and draft-persistence across unmounts
  • Redesigned Launcher, Widget, Chat, Header, and MessagesList components
  • New ChatPresentation component for the initial chat state
  • Redesigned ThinkingIndicator and updated TypingIndicator styles
  • Removed WaveformVisualizer component; simplified VoiceModeButton
  • Updated ConversationStarters and QuickReplies visuals
  • New icon added: rounded-x (default launcher icon)
  • Updated SCSS design tokens and variables

New Features

  • position parameter added, enabling the widget to be anchored to the bottom-left corner
  • Input draft text preserved in context so it survives InputBox unmounts
  • Suggested questions new behavior: starters are removed on first user interaction even if chat is closed
  • VTEX IO MinicartBridge utility for syncing cart state via setOrderForm
  • addProductToCart integration for VTEX storefronts
  • New VTEX sticky header CSS selectors to prevent the header from overlapping the widget
  • Header z-index override injected on widget mount as a fallback

Bug Fixes & Compatibility

  • Replaced URL.canParse with a try/catch block for broader browser compatibility
  • Fixed automatic textarea height adjustment
  • Fixed ESLint errors across multiple files

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 27, 2026

Codecov Report

❌ Patch coverage is 32.51534% with 550 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.94%. Comparing base (70fc2ac) to head (2b28c50).

Files with missing lines Patch % Lines
src/components/Messages/MessagesList.jsx 2.54% 115 Missing ⚠️
src/utils/VTEXIOMinicartBridge.js 10.00% 60 Missing and 12 partials ⚠️
src/contexts/OrderFormContext.jsx 15.25% 50 Missing ⚠️
src/components/common/Dropdown.jsx 4.65% 41 Missing ⚠️
src/contexts/ChatContext.jsx 28.26% 33 Missing ⚠️
src/components/Product/CounterControls.jsx 46.29% 29 Missing ⚠️
src/components/common/Tooltip.jsx 3.84% 25 Missing ⚠️
src/hooks/useVtexCxVisualViewportCssVars.js 10.71% 20 Missing and 5 partials ⚠️
src/components/Input/InputBox.jsx 62.71% 22 Missing ⚠️
src/components/Launcher/Launcher.jsx 37.50% 15 Missing ⚠️
... and 20 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #100      +/-   ##
==========================================
- Coverage   66.14%   61.94%   -4.21%     
==========================================
  Files          71       81      +10     
  Lines        3096     3747     +651     
  Branches      854     1024     +170     
==========================================
+ Hits         2048     2321     +273     
- Misses       1020     1378     +358     
- Partials       28       48      +20     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

cristiantela and others added 24 commits April 27, 2026 16:54
Creates src/styles/mixins.scss with scrollable-container, scrollable-content
and scrollbar-styles mixins. Registers the file in additionalData so it is
globally available without per-file @use imports. Replaces all duplicated
overflow/scrollbar declarations across views and components with @include calls.

Made-with: Cursor
Adds the #ADADAD gray token required by the scrollbar-styles mixin
for the default thumb color.

Made-with: Cursor
…hing

🐛 Resolve ESLint Silently Ignoring All Files in Flat Config
…veal

Introduces a hook that simulates a natural typing pace when streaming
messages arrive faster than 70 ms/word. Words are revealed one at a
time with a randomised delay (70 ± 20 ms) via recursive setTimeout,
so the animation never looks mechanical. The loop only stops after all
buffered words are shown AND the streaming status has ended, preventing
the effect from being cut short by a fast stream.

Also adds MessagesScrollContext to decouple the scroll-to-bottom
callback from the component tree, consumed directly by the hook.

Made-with: Cursor
…mingBuffer

Removes all buffering state, refs and effects from the component and
delegates them to useStreamingBuffer, keeping MessageText focused on
rendering. The caret indicator now follows isBuffering instead of
isStreaming, so it stays visible until the last word is revealed.

Made-with: Cursor
Adds isNearBottomRef to track scroll position without stale state and
scrollToBottomOnReveal (instant, near-bottom-only) provided via
MessagesScrollProvider. This keeps the list anchored to the bottom
while words are buffered, without interfering when the user has
scrolled up to read older messages.

Made-with: Cursor
Covers initial state, word-by-word reveal timing, onWordRevealed callback
invocation, mid-stream text growth, and the full streaming lifecycle
(buffering continues after status ends, stops only when queue is empty).
MessagesScrollContext tests verify null fallback outside the provider,
callback delivery, and re-render propagation.

Made-with: Cursor
✨ Centralise Scroll Styles into Reusable SCSS Mixins with Custom Scrollbar
✨ Simulate Word-by-Word Typing Pace for Streaming Messages
Handle messages of type "file" that arrive with a media_url and
optional caption instead of text. MessageDocument now defensively
reads metadata, falls back to inferring mimeType from the URL
extension, and displays caption when filename is unavailable.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Cover label fallback chain, mimeType inference from URL extension,
window.open gating by ALLOWED_DOCUMENT_TYPES, direction styling,
and MessageImage anchor (open in new tab) behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
✨ Handle `file` Message Type with mimeType Fallback and Image Open-in-New-Tab
…onent

Remove the count/max display logic from Badge, turning it into a
minimal dot indicator. Move absolute positioning from Launcher into
Badge itself so placement is self-contained.

Co-authored-by: Cursor <cursoragent@cursor.com>
Rename the Tooltip component to Notification and move it to
src/components/Notification/. Clicking the notification content now
opens the webchat via onOpen, and long messages are clamped to three
lines. The close button is prevented from shrinking on wide content.
Adds full unit test coverage for all new behaviour.

Co-authored-by: Cursor <cursoragent@cursor.com>
✨ Redesign Tooltip as Notification With Open-on-Click and Line Clamp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants