Skip to content

Track proposal diff row numbers using state#7473

Closed
jdolle wants to merge 1 commit intomainfrom
row-count-state
Closed

Track proposal diff row numbers using state#7473
jdolle wants to merge 1 commit intomainfrom
row-count-state

Conversation

@jdolle
Copy link
Copy Markdown
Collaborator

@jdolle jdolle commented Jan 8, 2026

Background

We want to be able to collapse unchanged rows to reduce noise on schema proposal diff. The current way of adding row numbers is by counting the classes using css. This doesn't work when rows get hidden.

Description

This adds logic to count the rows using context instead of relying on css. this allows us to show the row numbers even if rows are collapsed.

This may still yet change again depending on how rows are hidden.

@jdolle jdolle self-assigned this Jan 8, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @jdolle, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refactors the mechanism for displaying row numbers in the schema proposal diff view. By transitioning from CSS-driven counters to a state-managed approach using React Context, the system can now accurately maintain and display row numbers even when certain rows are hidden or collapsed, significantly improving the user experience for reviewing complex schema changes.

Highlights

  • Context-based Row Numbering: Implemented a new system to track schema diff row numbers using React Context, specifically AnnotatedContext, to ensure persistence even when rows are collapsed.
  • Removal of CSS Counters: Deprecated and removed the CSS-based counterIncrement properties and associated styles that previously handled row numbering, as they were incompatible with collapsible rows.
  • Integration of AnnotatedProvider: The SchemaDiff component is now wrapped with AnnotatedProvider to supply the necessary row number state to its children, enabling the new context-based numbering.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 8, 2026

🚀 Snapshot Release (alpha)

The latest changes of this PR are available as alpha on npm (based on the declared changesets):

Package Version Info
@graphql-hive/apollo 0.47.0-alpha-20260108014240-2cbf494fef8bf337c81f3c0aa00cff5e335dcffd npm ↗︎ unpkg ↗︎
@graphql-hive/cli 0.57.1-alpha-20260108014240-2cbf494fef8bf337c81f3c0aa00cff5e335dcffd npm ↗︎ unpkg ↗︎
@graphql-hive/core 0.20.0-alpha-20260108014240-2cbf494fef8bf337c81f3c0aa00cff5e335dcffd npm ↗︎ unpkg ↗︎
@graphql-hive/envelop 0.40.2-alpha-20260108014240-2cbf494fef8bf337c81f3c0aa00cff5e335dcffd npm ↗︎ unpkg ↗︎
@graphql-hive/yoga 0.47.0-alpha-20260108014240-2cbf494fef8bf337c81f3c0aa00cff5e335dcffd npm ↗︎ unpkg ↗︎
hive 8.14.1-alpha-20260108014240-2cbf494fef8bf337c81f3c0aa00cff5e335dcffd npm ↗︎ unpkg ↗︎

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 8, 2026

📚 Storybook Deployment

The latest changes are available as preview in: https://pr-7473.hive-storybook.pages.dev

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the schema diff component to track row numbers using React context instead of CSS counters, which is a necessary change to support collapsing unchanged rows. While the approach is directionally correct, the current implementation introduces critical bugs related to state management in React. Specifically, the row counters are not reset on re-renders, and state is mutated directly during the render phase using incorrect hooks. My review includes suggestions to fix these issues to ensure the component behaves predictably and correctly.

Comment on lines +79 to +83
const [context, _] = useState({
annotatedCoordinates: new Set<string>(),
oldDocumentRowNumber: 1,
newDocumentRowNumber: 1,
});
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.

critical

Using useState here creates a critical bug. The context object is created once and then mutated by child components (ChangeRow). Because useState preserves this object across re-renders of AnnotatedProvider, the row counters are never reset. This will cause row numbers to increment indefinitely on subsequent re-renders, leading to incorrect numbering. The context value must be reset for each render of the diff.

Suggested change
const [context, _] = useState({
annotatedCoordinates: new Set<string>(),
oldDocumentRowNumber: 1,
newDocumentRowNumber: 1,
});
const context = {
annotatedCoordinates: new Set<string>(),
oldDocumentRowNumber: 1,
newDocumentRowNumber: 1,
};

Comment on lines +141 to +150
const newDocumentRowNumber = useRef(ctx.newDocumentRowNumber);
const oldDocumentRowNumber = useRef(ctx.oldDocumentRowNumber);
if (props.type === 'addition') {
ctx.newDocumentRowNumber += 1;
} else if (props.type === 'removal') {
ctx.oldDocumentRowNumber += 1;
} else {
ctx.oldDocumentRowNumber += 1;
ctx.newDocumentRowNumber += 1;
}
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.

critical

This implementation has two critical issues:

  1. Incorrect useRef Usage: useRef preserves its value across renders. It will not be updated with the new value from ctx if this component re-renders, leading to stale row numbers. You should use simple variables to capture the value for the current render pass.

  2. Mutation During Render: Modifying context during render (ctx.newDocumentRowNumber += 1) is a side effect and a React anti-pattern. This will break in React's Strict Mode and is incompatible with concurrent features, leading to unpredictable behavior.

To fix the immediate bug with useRef, you should use simple variables. You will also need to update the JSX to access them directly (e.g., {oldDocumentRowNumber}) instead of via .current.

Suggested change
const newDocumentRowNumber = useRef(ctx.newDocumentRowNumber);
const oldDocumentRowNumber = useRef(ctx.oldDocumentRowNumber);
if (props.type === 'addition') {
ctx.newDocumentRowNumber += 1;
} else if (props.type === 'removal') {
ctx.oldDocumentRowNumber += 1;
} else {
ctx.oldDocumentRowNumber += 1;
ctx.newDocumentRowNumber += 1;
}
const newDocumentRowNumber = ctx.newDocumentRowNumber;
const oldDocumentRowNumber = ctx.oldDocumentRowNumber;
if (props.type === 'addition') {
ctx.newDocumentRowNumber += 1;
} else if (props.type === 'removal') {
ctx.oldDocumentRowNumber += 1;
} else {
ctx.oldDocumentRowNumber += 1;
ctx.newDocumentRowNumber += 1;
}

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 8, 2026

🐋 This PR was built and pushed to the following Docker images:

Targets: build

Platforms: linux/amd64

Image Tag: 2cbf494fef8bf337c81f3c0aa00cff5e335dcffd

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 8, 2026

💻 Website Preview

The latest changes are available as preview in: https://pr-7473.hive-landing-page.pages.dev

@jdolle
Copy link
Copy Markdown
Collaborator Author

jdolle commented Jan 15, 2026

This change is not necessary if we go the route of determining the lines/words first, then render.

@jdolle jdolle closed this Jan 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant