Skip to content

ComboboxControl: narrow onChange callback type to string | null - #81568

Merged
oandregal merged 4 commits into
trunkfrom
fix/combobox-control-onchange-value-type
Aug 14, 2026
Merged

ComboboxControl: narrow onChange callback type to string | null#81568
oandregal merged 4 commits into
trunkfrom
fix/combobox-control-onchange-value-type

Conversation

@oandregal

@oandregal oandregal commented Aug 13, 2026

Copy link
Copy Markdown
Member

Follow up to this comment.

What?

Narrows the ComboboxControl onChange callback parameter type from string | null | undefined to string | null by hoisting the value type into a named alias, and reverts the undefined widening that #81449 added to the DataForm combobox handler.

Why?

The onChange parameter was typed via an indexed access on the optional value prop:

type ComboboxControlProps = {
	value?: string | null;
	onChange?: ( value: CaseOne[ 'value' ] ) => void;
};

And so ComboboxControlProps[ 'value' ] (due to the ? modifier on value) leaks undefined into the onChange callback parameter type. The component never actually calls onChange with undefined — only with a suggestion string or null on reset — so consumers were forced to widen their handlers for a value that never arrives (as happened in #81449).

How?

By hoisting and sharing the type:

type ComboboxControlValue = string | null;
type ComboboxControlProps = {
	value?: ComboboxControlValue;
	onChange?: ( value: ComboboxControlValue ) => void;
};

Checked the impact on major consumers and there were no handler breaks.

Testing Instructions

  1. Run npm run build (or a TypeScript check) and confirm it passes.
  2. In packages/dataviews/src/components/dataform-controls/combobox.tsx, confirm the onChange handler typed ( newValue: string | null ) compiles without the previous | undefined widening.

Use of AI Tools

Authored with the assistance of Claude Code (implementation, consumer-impact analysis, and this description); reviewed and verified by me.

@github-actions github-actions Bot added [Package] Components /packages/components [Package] DataViews /packages/dataviews labels Aug 13, 2026
@oandregal oandregal changed the title ComboboxControl: Narrow the onChange callback value type to string | null ComboboxControl: narrow onChange callback type to string | null Aug 13, 2026
@oandregal oandregal added the [Type] Code Quality Issues or PRs that relate to code quality label Aug 13, 2026
@github-actions github-actions Bot added the [Package] Fields /packages/fields label Aug 13, 2026
@oandregal
oandregal marked this pull request as ready for review August 13, 2026 09:01
Copilot AI balanced review requested due to automatic review settings August 13, 2026 09:01
@oandregal
oandregal requested a review from a team as a code owner August 13, 2026 09:01
@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: oandregal <oandregal@git.wordpress.org>
Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org>
Co-authored-by: mcsf <mcsf@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

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

Narrows ComboboxControl’s callback type to match its runtime contract and updates affected consumers.

Changes:

  • Introduces a shared string | null value type.
  • Narrows three consumer handlers.
  • Updates package changelogs.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/components/src/combobox-control/types.ts Narrows the callback type.
packages/components/CHANGELOG.md Records the type change.
packages/dataviews/src/components/dataform-controls/combobox.tsx Narrows the DataForm handler.
packages/dataviews/CHANGELOG.md Records the internal update.
packages/fields/src/fields/parent/parent-edit.tsx Narrows the parent handler.
packages/fields/CHANGELOG.md Records the internal update.
packages/media-fields/src/attached_to/edit.tsx Narrows the attachment handler.
packages/media-fields/CHANGELOG.md Records the internal update.

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

* Function called with the selected value changes.
*/
onChange?: ( value: ComboboxControlProps[ 'value' ] ) => void;
onChange?: ( value: ComboboxControlValue ) => void;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@github-actions

Copy link
Copy Markdown

Size Change: 0 B

Total Size: 7.72 MB

compressed-size-action


Function called when the selected value changes.

- Type: `( value: string | null | undefined ) => void`

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The undefined type was even documented as something we supported.

@oandregal
oandregal requested review from ciampo and mirka August 13, 2026 09:14

@jorgefilipecosta jorgefilipecosta left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM 👍

@mcsf mcsf 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.

Glad my suggestion was helpful. :)

oandregal and others added 4 commits August 14, 2026 09:37
…null

The onChange parameter was typed via an indexed access on the optional
`value` prop, which leaked an accidental `undefined` into the union.
The component only ever calls onChange with a string or null, so hoist
the value type into a named alias and use it for both props.

This lets the DataForm combobox control drop the `undefined` widening
it had to add when vendoring ValidatedComboboxControl (#81449).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The parent field (@wordpress/fields) and attached_to field
(@wordpress/media-fields) carried the same `| undefined` widening in
their combobox onChange handlers, forced by the old callback type.
Narrow them to match the fixed upstream signature, and fill in the PR
number placeholders in the CHANGELOG entries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The rebase onto trunk landed after the 2026-08-12 release cut
(components 39.0.0, dataviews 18.0.0), leaving the entries stranded in
the released sections, which the CHANGELOG diff CI check rejects.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@oandregal
oandregal force-pushed the fix/combobox-control-onchange-value-type branch from 46e3ed4 to f201100 Compare August 14, 2026 07:38
@github-actions

Copy link
Copy Markdown

Flaky tests detected in f201100.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/31780731026
📝 Reported tests:

Should navigate inner blocks with arrow keys in /test/e2e/specs/editor/various/writing-flow.spec.js, passed after 1 failed attempt.
TimeoutError: locator.click: Timeout 10000ms exceeded.
Call log:
  - waiting for getByRole('listbox', { name: 'Blocks' }).getByRole('option', { name: 'Paragraph' })

    at WritingFlowUtils.addDemoContent (/home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/writing-flow.spec.js:1482:5)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/writing-flow.spec.js:30:3
adds and activates a new tab when pressing Enter at the end of a tab label in /test/e2e/specs/editor/blocks/tabs.spec.js, passed after 1 failed attempt.
Error: expect(locator).toHaveCount(expected) failed

Locator:  locator('[name="editor-canvas"]').contentFrame().getByRole('tab')
Expected: 3
Received: 2
Timeout:  5000ms

Call log:
  - Expect "toHaveCount" with timeout 5000ms
  - waiting for locator('[name="editor-canvas"]').contentFrame().getByRole('tab')
    14 × locator resolved to 2 elements
       - unexpected value "2"

    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/tabs.spec.js:146:25

@oandregal
oandregal enabled auto-merge (squash) August 14, 2026 08:43
@oandregal
oandregal merged commit 9f30bf7 into trunk Aug 14, 2026
72 of 82 checks passed
@oandregal
oandregal deleted the fix/combobox-control-onchange-value-type branch August 14, 2026 08:58
@github-actions github-actions Bot added this to the Gutenberg 23.9 milestone Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Components /packages/components [Package] DataViews /packages/dataviews [Package] Fields /packages/fields [Type] Code Quality Issues or PRs that relate to code quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants