Skip to content

UI: Add LoadingIndicator to item popups - #84633

Draft
mirka wants to merge 7 commits into
trunkfrom
item-popup-loading-indicator
Draft

mirka wants to merge 7 commits into
trunkfrom
item-popup-loading-indicator

Conversation

@mirka

@mirka mirka commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

What?

Add a LoadingIndicator subcomponent to Combobox, Autocomplete, SearchableSelect, SearchableChipSelect, SearchableSelectControl, and SearchableChipSelectControl.

The spinner is built in. The message defaults to translated Loading… and can be overridden through children.

Why?

The async examples currently compose a spinner and text in a Stack inside Status. Its padding and gap differ from popup items, so the loading row does not align with regular or creatable items.

How?

Share the popup item row layout with the loading indicator, including its prefix slot, padding, minimum height, and wrapping. Center an 8px spinner in the shared 16px icon slot and use the same vertical padding as the item list, so the icon center, text position, and popup height stay stable when loading resolves to a creatable item.

Compose the indicator inside the existing Status live region. The higher-level select components expose the same indicator for statusContent. Update the async examples, add a custom-message example beside regular and creatable items, and document the composition.

<Combobox.Status>
	{ loading ? (
		<Combobox.LoadingIndicator>Loading fruit…</Combobox.LoadingIndicator>
	) : null }
</Combobox.Status>

Testing Instructions

  1. In Storybook, open Combobox → With Loading Indicator and open the popup. The wrapped custom loading message and its spinner should align with the regular and creatable items below.

  2. Open Async Items for Combobox, Autocomplete, SearchableSelectControl, and SearchableChipSelectControl. Start loading by opening the select popup or typing in Autocomplete. Confirm the default loading row appears, then gives way to the results without an empty-results message during loading.

  3. Check With Loading Indicator with both Font only and WordPress global CSS. Emulate forced colors with WordPress global CSS and confirm the loading text and spinner remain visible.

  4. In SearchableChipSelect, open Async Items Permanent Loading and confirm the indicator stays visible. In Async Items With Creatable, type Mango and wait two seconds for matching options, then type Pineberry and wait for the creatable item. Every query change should restart loading, and rapid changes should resolve only the latest query. Confirm the icon center, text position, and popup height stay stable when loading resolves to the creatable item. Both stories are temporary and must be removed before merge.

Screenshots or screencast

The before/after pairs use the same viewport and loading state, captured at 2x and displayed at CSS size.

Component Before After
Combobox Combobox loading row before the shared item layout Combobox loading row using LoadingIndicator
Autocomplete Autocomplete loading row before the shared item layout Autocomplete loading row using LoadingIndicator

Custom loading text beside regular and creatable items:

WordPress global CSS WordPress global CSS with forced colors
Wrapped custom loading text aligned with regular and creatable items under WordPress global CSS Loading spinner and wrapped text visible alongside regular and creatable items in forced colors

Temporary SearchableChipSelect stories

Remove both temporary stories before merge.

Permanent loading:

Temporary SearchableChipSelect story with a permanently visible loading indicator

For the Pineberry query, the async story now shows a creatable item after loading when there are no matching options.

Before After
Before: the Pineberry query has no results and no creatable item After: the Pineberry query offers Create new fruit after loading

Each query change restarts the two-second loading state:

Loading results for the Pineberry query before matching or creatable options appear

@mirka mirka added the [Type] Enhancement A suggestion for improvement. label Oct 13, 2026
@mirka mirka self-assigned this Oct 13, 2026
@github-actions github-actions Bot added the [Package] UI /packages/ui label Oct 13, 2026
@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

📦 Bundle size

Size Change: +6.25 kB (+0.07%)

Total Size: 8.96 MB

📦 View Changed
Filename Size Change
build/modules/core-fields/post_type_supports.min.js 81.4 kB +377 B (+0.47%)
build/modules/workflow/index.min.js 89.9 kB +1.56 kB (+1.77%)
build/scripts/block-editor/index.min.js 600 kB +359 B (+0.06%)
build/scripts/block-library/index.min.js 443 kB +1.08 kB (+0.25%)
build/scripts/components/index.min.js 370 kB +228 B (+0.06%)
build/scripts/edit-site/index.min.js 417 kB +366 B (+0.09%)
build/scripts/editor/index.min.js 613 kB +1.31 kB (+0.21%)
build/scripts/format-library/index.min.js 89.9 kB +356 B (+0.4%)
build/scripts/media-utils/index.min.js 258 kB +382 B (+0.15%)
build/scripts/widgets/index.min.js 70.5 kB +220 B (+0.31%)

9f0a550 Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric 4aec2e9 trunk % Change
timeToFirstByte 32.35 ms +15.77% -2.78% 35.9 ms +11.56% -8.36% -9.89%
largestContentfulPaint 60 ms +6.67% -3.33% 64 ms +9.38% -3.13% -6.25%
lcpMinusTtfb 28.4 ms +2.29% -14.26% 26.35 ms +18.03% -7.97% 7.78%
wpBeforeTemplate 17.12 ms +19.86% -1.29% 18.7 ms +10.8% -5.88% -8.45%
wpTemplate 12.15 ms +5.93% -3.46% 13.65 ms +9.89% -10.48% -10.99%
wpTotal 29.66 ms +15.1% -3.2% 32.7 ms +11.28% -8.99% -9.3%
wpMemoryUsage 7.65 MB +0% -0% 7.59 MB +0% -0% 0.76%
wpDbQueries 16 +0% -0% 16 +0% -0% 0%

front-end-classic-theme

Metric 4aec2e9 trunk % Change
timeToFirstByte 28.15 ms +9.95% -4.26% 32.4 ms +3.4% -11.11% -13.12%
largestContentfulPaint 68 ms +0% -5.88% 72 ms +5.56% -5.56% -5.56%
lcpMinusTtfb 37.95 ms +6.46% -2.37% 39.3 ms +8.4% -4.45% -3.44%
wpBeforeTemplate 15.91 ms +5.59% -2.83% 17.68 ms +7.58% -6.96% -10.01%
wpTemplate 9.65 ms +2.69% -5.7% 11.15 ms +10.4% -11.39% -13.45%
wpTotal 25.64 ms +9.63% -3.9% 29.27 ms +4.58% -10.49% -12.4%
wpMemoryUsage 6.33 MB +0% -0% 6.27 MB +0% -0% 0.95%
wpDbQueries 13 +0% -0% 13 +0% -0% 0%

media-processing

Metric 4aec2e9 trunk % Change
mediaProcessingJpeg 219.45 ms +0.37% -1.5% 225.57 ms +1.94% -0.49% -2.71%
mediaProcessingAvif 3578.5 ms +1.86% -0.54% 3709.35 ms +0.67% -1.43% -3.53%
mediaProcessingJpegToAvif 2513.11 ms +2% -2.07% 2520.83 ms +1.79% -0.52% -0.31%

media-upload

Metric 4aec2e9 trunk % Change
jpegUploadProcessing 900.96 ms +6.09% -2.78% 1169.62 ms +20.25% -21.18% -22.97%
pngUploadProcessing 156.09 ms +1.11% -3.46% 168.1 ms +5.19% -8.27% -7.14%
largeJpegUploadProcessing 890.99 ms +0.48% -0.6% 905.6 ms +2.94% -1.68% -1.61%
multipleImageUploadProcessing 1048.33 ms +39.59% -1.59% 1484.33 ms +0.42% -0.88% -29.37%

post-editor

Metric 4aec2e9 trunk % Change
serverResponse 488.53 ms +8.16% -3.73% 518.2 ms +1.58% -8.25% -5.73%
firstPaint 364.58 ms +44.52% -33.82% 513.52 ms +5.59% -42.91% -29%
domContentLoaded 1204.55 ms +3.82% -2.19% 1207.51 ms +2.51% -1.24% -0.25%
loaded 1206.03 ms +3.8% -2.2% 1208.67 ms +2.52% -1.21% -0.22%
firstContentfulPaint 525.74 ms +1.15% -11.16% 538.11 ms +4.78% -5.79% -2.3%
firstBlock 3623.08 ms +0.31% -1.1% 3635.13 ms +0.58% -0.94% -0.33%
type 19.15 ms +2.98% -6.16% 20.27 ms +4.14% -5.57% -5.53%
typeWithoutInspector 19.32 ms +3.05% -5.23% 21.12 ms +1.99% -8.38% -8.52%
typeWithTopToolbar 25.33 ms +6.44% -8.57% 27.71 ms +4.51% -7.94% -8.59%
typeContainer 8.59 ms +9.2% -5.7% 8.96 ms +14.73% -6.92% -4.13%
focus 130.98 ms +3.1% -6.25% 125.33 ms +21.34% -4.29% 4.51%
firstFocus 245.71 ms +0% -0% 249.08 ms +0% -0% -1.35%
selectAll 610.35 ms +0.12% -5.24% 596.72 ms +7.94% -4.35% 2.28%
listViewOpen 82.81 ms +12.21% -8.63% 84.59 ms +2.32% -10.37% -2.1%
inserterOpen 47.82 ms +15.87% -16.19% 39.62 ms +9.29% -7.19% 20.7%
inserterHover 13.76 ms +4.72% -3.05% 12.26 ms +7.34% -11.01% 12.23%
inserterSearch 9.98 ms +2.2% -9.22% 9.67 ms +9.51% -5.89% 3.21%
loadPatterns 707.72 ms +1.4% -4.86% 666.36 ms +1.62% -1.77% 6.21%
wpTotal 477.94 ms +8.54% -3.74% 507.21 ms +1.78% -8.22% -5.77%
wpMemoryUsage 13.59 MB +0% -0% 13.48 MB +0% -0% 0.79%
wpDbQueries 55 +0% -1.82% 54 +0% -1.85% 1.85%

site-editor

Metric 4aec2e9 trunk % Change
serverResponse 279.35 ms +1.75% -7.94% 257.67 ms +2.61% -8.32% 8.41%
firstPaint 168.06 ms +12.89% -3.5% 195.27 ms +30.38% -8.93% -13.93%
domContentLoaded 887.16 ms +1.5% -0.3% 797.13 ms +1.31% -1.79% 11.29%
loaded 888.16 ms +1.49% -0.31% 798.09 ms +1.29% -1.77% 11.29%
firstContentfulPaint 400.54 ms +1.17% -1.06% 357.67 ms +0.64% -3.73% 11.99%
firstBlock 3170.49 ms +0.9% -1.17% 2928.47 ms +0.64% -1.55% 8.26%
type 14.68 ms +4.16% -2.79% 15.05 ms +2.86% -1.66% -2.46%
navigate 83.64 ms +20.09% -4.72% 82.46 ms +16.57% -5.28% 1.43%
loadPatterns 1058.65 ms +3.11% -17% 939.59 ms +8.98% -9.82% 12.67%
loadPages 979.86 ms +2% -0.5% 973.61 ms +2.89% -3.18% 0.64%
wpTotal 272.59 ms +1.79% -8.22% 251 ms +2.67% -8.59% 8.6%
wpMemoryUsage 12.63 MB +0% -0% 12.53 MB +0% -0% 0.86%
wpDbQueries 44.5 +1.12% -1.12% 44 +0% -2.27% 1.14%

9f0a550 Run

🏁 Flaky tests

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.

Regression: updating a specific option will only change its value and will not corrupt others in /test/e2e/specs/editor/various/core-settings.spec.js, passed after 1 failed attempt.
Error: expect(received).toStrictEqual(expected) // deep equality

- Expected  - 1
+ Received  + 1

  Array [
    "rewrite_rules",
-   "SERIALIZED DATA",
+   "",
  ]
    at forEach (/home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/core-settings.spec.js:46:26)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/core-settings.spec.js:43:35

9f0a550 Run

@mirka

mirka commented Oct 20, 2026

Copy link
Copy Markdown
Member Author

@WordPress/gutenberg-design Should we be scaling the Spinner stroke weight? It looks very off at the small size, especially in contrast to the tiny and thin checkmark/plus icons.

@jasmussen

jasmussen commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Should we be scaling the Spinner stroke weight? It looks very off at the small size, especially in contrast to the tiny and thin checkmark/plus icons.

I'll fight on this hill. But I won't die on it, so if I lose the fight, it's fine. I'm bullish on, at the very least by default the very thin 1.5px stroke we use across the editor. It's a bit of character, just like when cars design headlights and design a shape, so that 1.5px is a design characteristic. It repeats across progressbars, spinners, icons, and focus styles. And it's unique: the icon stroke width was deliberately set to 1.5 so as to differentiate itself from Material icons (at the time, 2px) and Apple icons (1px). This is the open web, this is our language, we're not the others.

Where I'm willing to lose the fight is if there's consensus: yeah make it thicker. But if that's the consensus, please do it across every progress indicator. Because if we change this, let's not arbitrarily erode the character one detail at a time, let's lean in and do it across.

@jameskoster

Copy link
Copy Markdown
Contributor

1.5px default seems fine. But I also like the principle that icons feel like they're part of the text which includes weight. I agree that the small spinner looks awkwardly hefty here:

Screenshot 2026-10-21 at 09 36 27

We scale icon stroke-width based on size, maybe we should do the same with the spinner?

@jasmussen

Copy link
Copy Markdown
Contributor

We scale icon stroke-width based on size, maybe we should do the same with the spinner?

Yes, solid point. One thing is a spinner in isolation, another is an inline spinner. Can it use the same rules as icons?

@mirka

mirka commented Oct 22, 2026

Copy link
Copy Markdown
Member Author

I tried adding the stroke scaling into Spinner, which should be largely equivalent to what we do with the icons. How does that look? #85378

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] UI /packages/ui [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants