npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

jb-image-input

v4.2.0

Published

image input web component

Readme

jb-image-input

Published on webcomponents.org GitHub license NPM Version GitHub Created At

Image input web component that lets the user select an image, preview it, and validate it.

  • Supports custom placeholder and overlay slots.
  • Supports required and max file size validation through jb-validation.

When to use

Use jb-image-input when the user must select an image and see an image preview inside the JB Design System UI. The basic setup is shown in the normal image input demo.

Use jb-file-input for non-image files or when previewing the selected file as an image is not required.

Demo

Using With JS Frameworks

See the React documentation.

Other integrations: Angular · Vue · Nuxt · Svelte · SvelteKit · SolidJS · Lit · Next.js · Astro · Blazor · Server-rendered templates · WordPress · Alpine.js and HTMX

Installation

npm i jb-image-input
import 'jb-image-input';
<jb-image-input label="Profile image"></jb-image-input>

API reference

Attributes

| name | type | default | description | | --- | --- | --- | --- | | name | string | "" | Form field name returned by the name property. Demo | | label | string | localized text | Placeholder title text and accessible aria label. Demo | | message | string | "" | Helper text shown in the placeholder message area and exposed as aria description. Demo | | required | boolean \| string | false | Enables required validation. A string value is used as the required error message. See required validation and the required message demo. | | multiple | boolean | false | Lets the hidden native file input accept multiple files. The component still previews the first file. See multi image selector and the multiple selection demo. | | accept | string | common image types | Native file accept string forwarded to the hidden file input. Demo | | is-uploading | boolean | false | Shows externally controlled upload loading state. | | disabled | boolean | false | Disables file selection and overlay actions. Demo |

Properties

| name | type | readonly | description | | --- | --- | --- | --- | | value | TValue \| null | no | Canonical value and form value. Selecting an image sets this to the selected File. Setting another value calls the optional downloader, or automatically loads a string URL. Demo | | file | File \| null | yes | Currently selected local file. Demo | | imageBase64Value | string \| null | no | Preview image data URL after the selected file is read or downloader resolves. Demo | | accept | string | no | Native file accept string forwarded to the hidden file input. Demo | | maxFileSize | number \| null | no | Maximum accepted file size in bytes. See max file size and the max-size demo. | | downloader | JBImageInputDownloader<TValue> | no | Optional function used to turn a stored value into a preview image. | | uploadPercent | number \| null | no | Visual upload progress percentage controlled by your upload flow. | | config | JBImageInputConfig | no | Developer-defined object passed to downloader. Demo | | multiple | boolean | no | Controls the hidden native file input multiple attribute. Demo | | required | boolean | no | Enables required validation. Demo | | disabled | boolean | no | Disables file selection and overlay actions, and sets disabled accessibility/custom state. Demo | | isUploading | boolean | no | Shows externally managed upload loading state. | | isLoading | boolean | yes | Computed aggregate loading state. | | status | 'empty' \| 'uploading' \| 'uploaded' \| 'downloaded' \| null | yes | Current visual state. Demo | | form | HTMLFormElement \| null | yes | Associated form from ElementInternals. | | selectedImageType | string \| undefined | yes | MIME type of the selected file, or undefined before a file is selected. | | validation | ValidationHelper<ValidationValue<TValue>> | yes | Validation helper from jb-validation; set validation.list for custom rules. Demo | | validationMessage | string | yes | Current native validation message from ElementInternals. Demo | | initialValue | TValue \| null | no | Default and reset value. It initializes value until the live value is explicitly set. | | isDirty | boolean | yes | true when current value differs from initialValue. Demo |

Methods

| name | returns | description | | --- | --- | --- | | openImageSelector() | void | Opens the hidden native file picker unless the component is disabled. Demo | | reset() | void | Restores initialValue and clears displayed validation. | | selectImageByFile(file) | Promise<void> | Injects a File as if the user selected it, validates it, previews it, and dispatches change when valid. Demo | | checkValidity() | boolean | Runs validation without showing the error message. Dispatches invalid when invalid. Demo | | reportValidity() | boolean | Runs validation and shows the first error message. Dispatches invalid when invalid. Demo | | JBImageInputWebComponent.ExtractBase64ImageFromFile(file) | Promise<string> | Static helper that reads a File and resolves its data URL. Demo |

Events

| event | detail | description | | --- | --- | --- | | change | none | Fired when a file is selected or the selected image is deleted. Uploading is handled by the application. Demo | | download-start | { value: TValue } | Cancelable event fired before a non-File value is converted to a preview. Prevent it when your application handles preview loading itself. | | image-selected | { files: FileList } | Fired after the hidden native file input changes. Use this for multi-image flows. Demo | | max-size-exceed | { file: File } | Fired when the selected file is larger than maxFileSize. Demo | | invalid | none | Fired when checkValidity() or reportValidity() finds an invalid value. Demo |

Value, file, and preview

file is the selected local File. The initial value demo shows how the local file, current value, initial value, and dirty state relate.

value is the value your app stores and the value passed to ElementInternals.setFormValue(). Selecting an image sets value to the selected File; upload the file in your change handler and assign any returned application value yourself.

For native form submission, keep the value compatible with setFormValue: File, string, FormData, or null. If your API returns an object, store a string id/URL for form submission or serialize the object before assigning it as value.

When you set value programmatically:

  • If value is a File, the component reads it and shows a preview.
  • If value is not a File, the component dispatches download-start. If it is not canceled, it calls downloader(value, config) when configured, or fetches string URL values itself.

Upload and download behavior

jb-image-input does not own your upload request. Listen for change, upload event.target.value yourself, and set isUploading/uploadPercent while the request is in progress. The optional downloader handles stored values that need custom preview conversion.

The default delete action uses jb-icon-delete; its lid animation plays while the delete control is hovered.

const imageInput = document.querySelector('jb-image-input');

imageInput.downloader = (value, config) => {
    return fetch(value)
      .then((response) => response.blob())
      .then((blob) => new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result);
        reader.onerror = reject;
        reader.readAsDataURL(blob);
      }));
};

| downloader argument | description | | --- | --- | | file | The File value selected by the user. | | config | Developer-defined config object stored on the component and passed to downloader. | | value | Current component value passed to downloader; commonly an id or URL. |

Validation

jb-image-input uses jb-validation. Built-in validation covers required and maxFileSize; custom validations can be added with validation.list. See the required validation demo and max-size demo.

const imageInput = document.querySelector('jb-image-input');

imageInput.validation.list = [
  {
    validator: ({ file }) => !file || file.size < 500 * 1024,
    message: 'Image must be smaller than 500KB',
  },
];

const isValid = imageInput.reportValidity();

Required validation

<jb-image-input required></jb-image-input>
<jb-image-input required="Please select an image"></jb-image-input>

Max file size

Set maxFileSize in bytes; the max-size demo shows the rejection event:

const imageInput = document.querySelector('jb-image-input');
imageInput.maxFileSize = 2 * 1024 * 1024;

imageInput.addEventListener('max-size-exceed', (event) => {
  alert(`Selected image is ${event.detail.file.size} bytes`);
});

Multi image selector

jb-image-input previews and uploads one image. To build a multi-image UI, set multiple, listen to image-selected, render one component per extra file, and call selectImageByFile(file) on each new component. The multiple selection demo shows the native input configuration.

<jb-image-input multiple="true"></jb-image-input>
const imageInputs = document.querySelector('#image-inputs');
const firstInput = imageInputs.querySelector('jb-image-input');

firstInput.addEventListener('image-selected', (event) => {
  const [, ...extraFiles] = Array.from(event.detail.files);

  extraFiles.forEach((file) => {
    const input = document.createElement('jb-image-input');
    imageInputs.appendChild(input);
    input.selectImageByFile(file);
  });
});

Image accept type

Set accept to constrain the native file picker; the multiple selection demo shows the accepted MIME types.

document.querySelector('jb-image-input').accept = 'image/jpeg,image/jpg,image/png,image/svg+xml';

Slots

Use the custom placeholder demo to see the placeholder slot in context.

| slot | description | | --- | --- | | placeholder | Custom content shown while the component status is empty. | | overlay | Replaces the full image overlay shown over the preview image. | | overlay-content | Replaces the default overlay controls while keeping the default overlay container. |

<jb-image-input label="Profile image">
  <div slot="placeholder">
    Select profile image
  </div>
</jb-image-input>

CSS parts and states

| part | description | | --- | --- | | message | Helper or validation message inside the default placeholder. |

| custom state | description | | --- | --- | | disabled | Applied when disabled is true. |

jb-image-input::part(message) {
  font-weight: 600;
}

jb-image-input:state(disabled) {
  opacity: 0.5;
}

Custom style

Set CSS variables in the parent scope of the component.

For complete styling guidance, live examples, official parts and states, and the full CSS variable reference, see Styling or the style gallery.

jb-image-input.avatar-input {
  --jb-image-input-width: 10rem;
  --jb-image-input-height: 10rem;
  --jb-image-input-border-radius: 50%;
}

Accessibility notes

The normal image input demo includes the label and helper message used for the accessible name and description.

  • The shadow root uses delegatesFocus.
  • The component is form-associated and passes value to ElementInternals.setFormValue().
  • label is exposed as the component aria label and default placeholder title.
  • message is exposed as the component aria description.
  • Validation state is synchronized with ElementInternals where the browser supports it.

Related Docs

AI agent notes

  • Import jb-image-input once before using <jb-image-input>.
  • Use value for the stored/submitted image value and file for the selected local File.
  • Provide downloader when a stored value needs custom preview conversion.
  • Keep submitted values compatible with ElementInternals.setFormValue(): File, string, FormData, or null.
  • Use image-selected when implementing multi-image selection; the component itself previews/uploads the first selected file.
  • Use accept, maxFileSize, validation.list, and required instead of custom file filtering logic when possible.
  • This package includes custom-elements.json and points to it with the package.json customElements field. The field is documented by the Custom Elements Manifest project in Referencing manifests from npm packages.
  • In custom-elements.json, exports.kind: "js" describes the JavaScript/TypeScript class export and exports.kind: "custom-element-definition" maps the jb-image-input tag name to that class.