Skip to content

fix(highlight): keep separator state when reverse-highlight siblings disagree#7079

Merged
Haroenv merged 2 commits into
masterfrom
fix/reverse-highlight-sibling-state
Jun 26, 2026
Merged

fix(highlight): keep separator state when reverse-highlight siblings disagree#7079
Haroenv merged 2 commits into
masterfrom
fix/reverse-highlight-sibling-state

Conversation

@Haroenv

@Haroenv Haroenv commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

What's broken

getHighlightFromSiblings (used by reverseHighlightedParts for reverse-highlight / reverse-snippet) computes neighbor highlight state with ||:

const isNextHighlighted = parts[i + 1]?.isHighlighted || true;
const isPreviousHighlighted = parts[i - 1]?.isHighlighted || true;

X || true is always true, even when the neighbor exists and is genuinely false. So the isPreviousHighlighted === isNextHighlighted guard is always satisfied, and every separator part is treated as inheriting its siblings' highlight state — even when the siblings disagree. For a value where a separator sits between a highlighted and a non-highlighted segment, the reverse-highlight / reverse-snippet output is wrong.

Why it happens

|| was used where a "default only when the neighbor is missing" was intended — the ?. optional chaining shows the intent. false || true collapses a real false neighbor to true.

Fix

Use ?? so the true default applies only when the neighbor is absent (undefined). This changes behavior only in the present-and-false case (the bug); missing-sibling behavior is preserved byte-for-byte, so no currently-correct case regresses.

?? is already used throughout instantsearch.js source, so the toolchain supports it.

Test

Added a regression case: a separator between a highlighted and a non-highlighted segment keeps its own state. Fails before, passes after.

Context

Mirrors algolia/autocomplete#1348, which fixes the same bug in the autocomplete-preset-algolia port of this sibling strategy. The autocomplete code was a faithful port of this function — including the || true — so the bug exists in both repos.

🤖 Generated with Claude Code

Test update

Updated the existing reverseHighlightedParts "multiple matches" expectation: it asserted the buggy output (a separator between two non-highlighted parts reversed to non-highlighted, breaking an otherwise contiguous reverse-highlighted run). With the fix the separator correctly inherits its agreeing siblings, so the reversed "Fi - Black" run is uniformly highlighted. Note: the equivalent autocomplete repo has no test covering this "separator between two present, agreeing neighbors" path, which is why algolia/autocomplete#1348 went green without a test change.

…disagree

`getHighlightFromSiblings` defaulted neighbor highlight state with `|| true`:

    const isNextHighlighted = parts[i + 1]?.isHighlighted || true;
    const isPreviousHighlighted = parts[i - 1]?.isHighlighted || true;

`X || true` is always `true`, even when the neighbor exists and is genuinely
`false`. So the `isPreviousHighlighted === isNextHighlighted` guard is always
satisfied and every separator part is treated as inheriting its siblings'
highlight state — even when the siblings disagree. For a value where a
separator sits between a highlighted and a non-highlighted segment, the
reverse-highlight / reverse-snippet output is wrong.

The `?.` optional chaining shows the intent was "default only when the neighbor
is missing". Use `??` so the `true` default applies only when the neighbor is
absent (`undefined`), preserving a real `false`.

Mirrors algolia/autocomplete#1348, which fixes the same bug in the
`autocomplete-preset-algolia` port of this sibling strategy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

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

@Haroenv Haroenv marked this pull request as ready for review June 19, 2026 14:39
@Haroenv Haroenv requested review from a team, FabienMotte, Copilot and shaejaz and removed request for a team June 19, 2026 14:39

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

Fixes incorrect reverse-highlight / reverse-snippet behavior where separator parts could incorrectly inherit highlight state due to using || true (which collapses real false to true) when computing sibling highlight state.

Changes:

  • Replace || true with ?? true in getHighlightFromSiblings so the default applies only when a sibling is missing.
  • Add a regression test ensuring separators keep their own state when adjacent siblings disagree.

Reviewed changes

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

File Description
packages/instantsearch.js/src/lib/utils/getHighlightFromSiblings.ts Uses nullish coalescing to correctly preserve false sibling highlight states.
packages/instantsearch.js/src/lib/utils/tests/getHighlightFromSiblings-test.ts Adds regression coverage for the “siblings disagree around a separator” case.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@pkg-pr-new

pkg-pr-new Bot commented Jun 19, 2026

Copy link
Copy Markdown
More templates

algoliasearch-helper

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

instantsearch-ui-components

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

instantsearch.css

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

instantsearch.js

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

react-instantsearch

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

react-instantsearch-core

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

react-instantsearch-nextjs

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

react-instantsearch-router-nextjs

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

vue-instantsearch

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

commit: ef0738e

@FabienMotte FabienMotte changed the title fix(highlight): keep separator state when reverse-highlight siblings disagree fix(instantsearch.js): keep separator state when reverse-highlight siblings disagree Jun 19, 2026
… sibling logic

The "multiple matches" case asserted the buggy output: a separator between two
non-highlighted parts ('Fi' and 'Black') was reversed to non-highlighted,
leaving a gap in an otherwise contiguous reverse-highlighted run. With the
`?? true` fix the separator correctly inherits its (agreeing) siblings, so the
reversed "Fi - Black" run is now uniformly highlighted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Haroenv Haroenv changed the title fix(instantsearch.js): keep separator state when reverse-highlight siblings disagree fix(highlight): keep separator state when reverse-highlight siblings disagree Jun 25, 2026
@Haroenv Haroenv merged commit b7a0f60 into master Jun 26, 2026
15 of 16 checks passed
@Haroenv Haroenv deleted the fix/reverse-highlight-sibling-state branch June 26, 2026 11:15
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