Skip to content

feat(chat): customizable loader placement, rendering and timing - #7171

Draft
shaejaz wants to merge 3 commits into
masterfrom
refactor/chat-loader-states
Draft

feat(chat): customizable loader placement, rendering and timing#7171
shaejaz wants to merge 3 commits into
masterfrom
refactor/chat-loader-states

Conversation

@shaejaz

@shaejaz shaejaz commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Why

The chat loader was effectively fixed in place and hardcoded: it could only render at the end of the messages list, its display logic lived in the UI component with no way to influence it, the suggestions row appeared out of nothing at the end of a turn, and it visibly popped in and out mid-answer.

That last one had two causes. Parts that render nothing still answered for the turn's progress — a trailing data-* payload, a text part created by text-start before its first delta — which findLastProgressPart now makes transparent. And the remaining sub-perceptual toggles are absorbed by timing: a loader returning mid-turn waits out loaderShowDelay, a visible one holds for loaderMinDuration, and honest long waits are untouched. Visibility is derived during render rather than from an effect, which would land a frame after the state it announces.

API

ChatMessages, forwarded by both the JS widget and React <Chat>:

Prop Type Default
loaderPosition 'messages-end' | 'message-inline' 'messages-end'
shouldShowLoader (ctx: ChatLoaderContext & { defaultValue: boolean }) => boolean
loaderShowDelay number (ms) 250
loaderMinDuration number (ms) 200

translations.loaderText widens from string to also accept (ctx: ChatLoaderContext) => string, and loaderComponent now receives the turn context (status, phase, message, messages, tools) plus inline. shouldShowLoader gets the built-in decision as defaultValue so an override narrows it instead of reimplementing it. ChatMessage gains loaderElement, so a custom messageComponent can place the loader itself.

New exported types: ChatLoaderPosition, ChatLoaderPhase ('submitted' | 'tool' | 'reasoning' | 'thinking'), ChatLoaderContext.

Alongside: aria-busy on the messages log, a loader fade-in with a prefers-reduced-motion override and no exit animation, and an inline loader variant without the message chrome.

Suggestions

ChatPromptSuggestions gains isLoading, skeletonCount and classNames.skeleton / classNames.skeletonItem, mirroring standalone PromptSuggestions; it also filters blank suggestions and ignores clicks while loading. connectChat exposes suggestionsStatus ('idle' | 'loading') to drive it, inferring "still coming" from a running turn with no data-suggestions part yet, gated on evidence that suggestions are expected at all (metadata.suggestionsEnabled, or an earlier turn in the conversation produced some) so an agent that never sends them shows no placeholder.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 121 complexity

Metric Results
Complexity 121

View in Codacy

TIP This summary will be updated as you push new changes.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the Chat widget across the connector, UI components, and framework wrappers (InstantSearch.js + React) by making loader behavior customizable (placement, timing, and rendering context) and by adding a “suggestions loading” state with skeleton placeholders.

Changes:

  • Add loader customization options (position, show override, show delay, min duration) and richer loader context (status/phase/message/tools), plus inline loader rendering.
  • Introduce suggestionsStatus in connectChat and propagate it to UI to drive suggestion skeleton placeholders and click-guarding while loading.
  • Add supporting CSS (loader fade-in, inline loader styling, suggestion skeleton pills) and expand/adjust test coverage (UI + common + connector tests).

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/common/widgets/chat/options.tsx Adds common widget tests for loader behavior (data-part trailing) and loader customization, plus suggestions placeholders behavior.
packages/react-instantsearch/src/widgets/Chat.tsx Threads new loader props and suggestionsStatus into the React <Chat /> wrapper.
packages/instantsearch.js/src/widgets/chat/chat.tsx Threads new loader props and suggestionsStatus into the InstantSearch.js widget renderer/templates.
packages/instantsearch.js/src/connectors/chat/connectChat.ts Adds suggestionsStatus derivation logic and exposes it via render state.
packages/instantsearch.js/src/connectors/chat/tests/connectChat-test.ts Adds unit tests covering suggestionsStatus state derivation.
packages/instantsearch.css/src/components/chat/_chat-suggestions.scss Styles ChatPromptSuggestions skeleton placeholders.
packages/instantsearch.css/src/components/chat/_chat-message-loader.scss Adds loader enter animation, reduced-motion override, and inline loader styling.
packages/instantsearch-ui-components/src/lib/utils/chat.ts Adds utilities to ignore non-rendering parts for “progress” computations (findLastProgressPart).
packages/instantsearch-ui-components/src/components/chat/types.ts Introduces exported loader-related types (ChatLoaderPosition, ChatLoaderPhase, ChatLoaderContext).
packages/instantsearch-ui-components/src/components/chat/ChatPromptSuggestions.tsx Adds loading/skeleton rendering, blank filtering, and click suppression while loading.
packages/instantsearch-ui-components/src/components/chat/ChatMessages.tsx Implements loader visibility smoothing, inline loader placement, loader context/phase, aria-busy, and “pending suggestions” mounting.
packages/instantsearch-ui-components/src/components/chat/ChatMessageLoader.tsx Extends loader props to include turn context and adds inline rendering variant.
packages/instantsearch-ui-components/src/components/chat/ChatMessage.tsx Adds loaderElement slot to render an inline loader under message parts.
packages/instantsearch-ui-components/src/components/chat/Chat.tsx Wires suggestions loading into ChatMessages and updates hook wiring passed to the factory component.
packages/instantsearch-ui-components/src/components/chat/tests/ChatPromptSuggestions.test.tsx Adds tests for skeleton rendering, blank filtering, and click suppression while loading.
packages/instantsearch-ui-components/src/components/chat/tests/ChatMessages.test.tsx Adds extensive tests for loader visibility smoothing, context passing, inline rendering, and pending suggestions.
packages/instantsearch-ui-components/src/components/chat/tests/Chat.test.tsx Updates factory wiring to include the new hooks passed through to ChatMessages.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +505 to +507
if (!isVisible && state.isVisible) {
state.hasHiddenInTurn = true;
}
}

return (
<div className={cx('ais-ChatPromptSuggestions', classNames.root)}>
@pkg-pr-new

pkg-pr-new Bot commented Aug 18, 2026

Copy link
Copy Markdown
More templates

algoliasearch-helper

npm i https://pkg.pr.new/algolia/instantsearch/algoliasearch-helper@7171

instantsearch-ui-components

npm i https://pkg.pr.new/algolia/instantsearch/instantsearch-ui-components@7171

instantsearch.css

npm i https://pkg.pr.new/algolia/instantsearch/instantsearch.css@7171

instantsearch.js

npm i https://pkg.pr.new/algolia/instantsearch/instantsearch.js@7171

react-instantsearch

npm i https://pkg.pr.new/algolia/instantsearch/react-instantsearch@7171

react-instantsearch-core

npm i https://pkg.pr.new/algolia/instantsearch/react-instantsearch-core@7171

react-instantsearch-nextjs

npm i https://pkg.pr.new/algolia/instantsearch/react-instantsearch-nextjs@7171

react-instantsearch-router-nextjs

npm i https://pkg.pr.new/algolia/instantsearch/react-instantsearch-router-nextjs@7171

vue-instantsearch

npm i https://pkg.pr.new/algolia/instantsearch/vue-instantsearch@7171

commit: 1ff8eca

@github-actions

Copy link
Copy Markdown

Size Change: +5.92 kB (+0.48%)

Total Size: 1.23 MB

📦 View Changed
Filename Size Change
packages/instantsearch.css/components/chat-min.css 6.42 kB +86 B (+1.36%)
packages/instantsearch.css/components/chat.css 6.86 kB +86 B (+1.27%)
packages/instantsearch.css/themes/algolia-min.css 10.9 kB +96 B (+0.89%)
packages/instantsearch.css/themes/algolia.css 11.5 kB +102 B (+0.89%)
packages/instantsearch.css/themes/nova-min.css 11 kB +111 B (+1.02%)
packages/instantsearch.css/themes/nova.css 11.7 kB +102 B (+0.88%)
packages/instantsearch.css/themes/satellite-min.css 11.7 kB +106 B (+0.91%)
packages/instantsearch.css/themes/satellite.css 12.6 kB +106 B (+0.85%)
packages/instantsearch.js/dist/instantsearch.development.js 303 kB +2.81 kB (+0.93%)
packages/instantsearch.js/dist/instantsearch.production.min.js 143 kB +1.11 kB (+0.78%)
packages/react-instantsearch-core/dist/umd/ReactInstantSearchCore.min.js 67.9 kB +108 B (+0.16%)
packages/react-instantsearch/dist/umd/ReactInstantSearch.min.js 114 kB +1.1 kB (+0.97%)
ℹ️ View Unchanged
Filename Size Change
packages/algolia-experiences/dist/algolia-experiences.development.js 179 kB 0 B
packages/algolia-experiences/dist/algolia-experiences.production.min.js 81.4 kB 0 B
packages/algoliasearch-helper/dist/algoliasearch.helper.js 44.3 kB 0 B
packages/algoliasearch-helper/dist/algoliasearch.helper.min.js 13.9 kB -1 B (-0.01%)
packages/instantsearch.css/components/ai-mode-button.css 1.75 kB 0 B
packages/instantsearch.css/components/autocomplete-min.css 4.31 kB 0 B
packages/instantsearch.css/components/autocomplete.css 4.66 kB 0 B
packages/instantsearch.css/components/button.css 1.96 kB 0 B
packages/instantsearch.css/components/filter-suggestions.css 1.88 kB 0 B
packages/instantsearch.css/themes/reset-min.css 1.3 kB 0 B
packages/instantsearch.css/themes/reset.css 1.38 kB 0 B
packages/vue-instantsearch/vue2/cjs/index.js 19.9 kB 0 B
packages/vue-instantsearch/vue2/umd/index.js 73.3 kB -6 B (-0.01%)
packages/vue-instantsearch/vue3/cjs/index.js 20.6 kB 0 B
packages/vue-instantsearch/vue3/umd/index.js 73.7 kB -5 B (-0.01%)

compressed-size-action

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.

2 participants