Skip to content

fix: support coordinate objects from image inputs in remote forms - #16944

Merged
Rich-Harris merged 4 commits into
version-3from
input-type-image
Aug 27, 2026
Merged

fix: support coordinate objects from image inputs in remote forms#16944
Rich-Harris merged 4 commits into
version-3from
input-type-image

Conversation

@paoloricciuti

Copy link
Copy Markdown
Member

I was today years old when I discovered <input type="image" /> and how it works and it got me unreasonably excited. So obviously, I had to try if it worked correctly with remote functions, and it turns out it doesn't.

This PR fixes that.

How it works in HTML

Initially, I thought that <input type="image" /> was just to show an image as a submit button, a relic of an era where you couldn't properly style buttons. But it turns out that it does something much more interesting. Because when you submit a form with <input type="image" /> two properties are added to the FormData (or to the search): name.x and name.y with the coordinates of where the pointer was (inside the image) when it was clicked.

I legit never used it, but I can see how this could sometimes be necessary, and it would be a shame to lose this progressive enhanced functionality.

The fix

The fix works both type wise and runtime wise by allowing the user to declare as("image") when the field is an object with x and y as numbers.

A few important notes:

  • If it has any other property you can't specify field.as("image") as you would have no way to set the last property
  • You can still set field.x.as("text") and field.y.as("text") so if by chance you have an { x: number; y: number } schema, but it's not for an image input you can still use them.

Now the kind-of bad news: I think this is a breaking change in case someone was using as("image") on a field which was not { x: number; y: number }...however this would've error at runtime before (because of the extra fields) so maybe is acceptable?

P.s. I know AIs love to write in paragraphs, but this was handwritten lol

@pkg-svelte-dev

pkg-svelte-dev Bot commented Aug 26, 2026

Copy link
Copy Markdown

Install the latest version of @sveltejs/kit from 415fcdc:

pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/415fcdcea8ae9ebb5b29c963b0278f4ca85eb06d

Open in pkg.svelte.dev: https://pkg.svelte.dev/repos/kit/pr/16944

@changeset-bot

changeset-bot Bot commented Aug 26, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 415fcdc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sveltejs/kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@svelte-docs-bot

Copy link
Copy Markdown

@svelte-triage-bot

This comment was marked as resolved.

@Nic-Polumeyv

Copy link
Copy Markdown
Contributor

handle_submit in form.svelte.js runs the submitter mirror for the image input too. Its value is '', so coerce_form_value('number', '') returns undefined and input.position is overwritten on every enhanced submit. After fields.position.set({ x: 1, y: 2 }) a click leaves value() as undefined; the server side is fine because the body comes from form_data, which is why the e2e passes. The coordinates are already in form_data, so image can skip the block:

if (event.submitter && /** @type {HTMLInputElement} */ (event.submitter).type !== 'image') {

Comment thread packages/kit/src/runtime/app/server/public.d.ts Outdated
@Nic-Polumeyv

Copy link
Copy Markdown
Contributor

The default-submitter selector in submit() / validate() never matches <input type=image>, so with oninput={() => form.validate()} the coordinates drop out after a failed submit and the image renders aria-invalid until the next click. An image input is a submit button and the browser sends (0, 0) for it on implicit submission, so [type="image"] in the selector is enough.

Co-authored-by: Nic Polumeyv <nicolas.polum@gmail.com>
Rich-Harris pushed a commit that referenced this pull request Aug 27, 2026
Fixes a pre-existing async live-query test flake observed on
#16944 in CI run
https://github.com/sveltejs/kit/actions/runs/32994679500.

The stats button previously awaited `get_stats()` without first
refreshing its cached query. Cache eviction therefore depended on
`FinalizationRegistry`/GC timing, and CI polling could repeatedly read
the original `cleanup_count` after reconnecting.

Explicitly start a refresh, then await `get_stats()` again. Query
proxies for the same query share the cached resource, so the second
proxy resolves with fresh server state while using the idiomatic
remote-query API.

The follow-up passed async-app type checking, formatting, and diff
validation. A targeted Playwright build also completed, though browser
launch was unavailable in the sandbox because required Chromium system
libraries could not be installed.

---------

Co-authored-by: svelte-triage-bot <team@svelte.com>
@Rich-Harris

Copy link
Copy Markdown
Member

/autofix

@Rich-Harris Rich-Harris 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.

image

@Rich-Harris
Rich-Harris merged commit e7c74bf into version-3 Aug 27, 2026
40 checks passed
@Rich-Harris
Rich-Harris deleted the input-type-image branch August 27, 2026 21:59
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