Upload
DraftA file upload field with drag and drop, file type and size limits, and a list of selected files.
Preview
Code
Install
npm install @fbin-web/neighborhood-core
Import
import { NbhdUpload } from '@fbin-web/neighborhood-core';
Usage
<nbhd-upload
label="Upload photos"
help-text="Add a clear photo of the product label."
upload-type="image"
multiple
max-files="3"
max-file-size="5242880">
</nbhd-upload>
<script>
const nbhdUpload = document.querySelector('nbhd-upload');
nbhdUpload.addEventListener('nbhd-files-selected', (event) => {
console.log(event.detail.files);
});
</script>
Install
npm install @fbin-web/neighborhood-react
Import
import { NbhdUpload } from '@fbin-web/neighborhood-react';
Usage
import { NbhdUpload } from '@fbin-web/neighborhood-react';
const App = () => (
<>
<NbhdUpload
label="Upload photos"
helpText="Add a clear photo of the product label."
uploadType="image"
multiple
maxFiles={3}
maxFileSize={5 * 1024 * 1024}
onNbhdFilesSelected={(event) => console.log(event.detail.files)}></NbhdUpload>
</>
);
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
label | label | string | '' | Visible label for the upload field. |
helpText | help-text | string | '' | Help text shown below the drop zone when not invalid. |
errorText | error-text | string | '' | Error text shown when invalid is set. |
invalid | invalid | boolean | false | Marks the upload as invalid and shows the error text. |
instructions | instructions | string | 'Drag and drop a file here or' | Text inside the drop zone, before the browse button. Uses "files" when multiple is set. |
browseLabel | browse-label | string | 'Browse files' | Label for the browse button. |
browseVariant | browse-variant | primarysecondarytertiaryplainlinkunstyled | 'primary' | Button variant for the browse button. |
uploadType | upload-type | imagefile | 'image' | Preset of accepted file types. Ignored when accept is set. |
accept | accept | string | '' | Native accept string that overrides upload-type, e.g. image/*,.pdf. |
multiple | multiple | boolean | false | Allows more than one file. Without it, a new file replaces the current one. |
maxFiles | max-files | number | — | Maximum number of files when multiple is set. |
maxFileSize | max-file-size | number | — | Maximum size of each file, in bytes. |
name | name | string | '' | Field name for consumers to use when appending files to FormData. The form field name it submits under. |
disabled | disabled | boolean | false | Disables the browse button, drop zone and remove buttons. |
required | required | boolean | false | At least one file must be chosen before the owning form submits. Shows the required marker on the label. |
requiredLabel | required-label | string | Required | Announced with the Browse button when `required`, since the visual * marker is hidden from screen readers. |
surface | surface | noneprimarysecondaryinverseinverse-secondary | 'primary' | Surface the upload sits on. Colors follow the surface control colors. |
ariaLabel | aria-label | string | '' | Accessible name used when no visible label is set. |
fileListLabel | file-list-label | string | Selected files | Accessible name of the list of selected files. |
cssClass | css-class | string | '' | Custom CSS class for the base wrapper. |
files | — | File[] | [] | Read-only copy of the selected files. |
No properties match.
Events
| Name | Description | Event Detail |
|---|---|---|
nbhd-files-selected | Emitted when files are added or removed. | { files: File[] } |
nbhd-files-rejected | Emitted when files are not added because of their type, size or the file limit. | { rejected: { file: File, reason: 'type' | 'size' | 'count' }[] } |
nbhd-file-removed | Emitted when a file is removed from the selection. | { file: File, files: File[] } |
Form methods
Form-associated: submits the chosen files under `name` (one entry per file). With `required`, no file blocks submission. Reset clears the selection.
| Name | Description |
|---|---|
checkValidity() | Returns false (and fires `invalid`) if the control fails validation. |
reportValidity() | Like checkValidity(), and shows the browser’s validation message on the control. |
setCustomValidity(message) | Marks the control invalid with your own message; an empty string clears it. |
validity | The ValidityState (valueMissing, typeMismatch, customError, …). |
validationMessage | The message the browser would show. |
willValidate | Whether the control takes part in form validation (false when disabled). |
associatedForm | The |
No form methods match.
Slots
| Name | Description |
|---|---|
label | Custom content for the label. Defaults to the label property. |
icon | Replaces the upload icon in the drop zone. |
instructions | Replaces the drop zone instructions text. |
help | Help text shown when not invalid. |
error | Error text shown when invalid. |
requirements | Replaces the generated accepted types and limits text. |
No slots match.
CSS Parts
| Name | Description |
|---|---|
base | The form control wrapper. |
label | The label wrapper. |
dropzone | The drag and drop area. |
icon | The icon wrapper. |
instructions | The instructions wrapper. |
browse-button | The browse button. |
text | The wrapper for help, error, rejection and requirements text. |
help | The help slot. |
error | The error slot. |
rejections | The list of files that were not added. |
requirements | The requirements slot. |
file-list | The list of selected files. |
file | A selected file. |
thumbnail | The image preview or file type icon. |
file-name | The file name. |
file-meta | The file size. |
remove-button | The remove button for a file. |
No css parts match.
nbhd-upload::part(base) {
/* your styles */
}
CSS Properties
Set these on nbhd-upload or an ancestor to override the defaults. Token is the design token a default comes from and Value is what it resolves to in core Neighborhood; brands may override them. Properties that adapt to surface follow the light or inverse surface they sit on until you set them.
Upload
| Property | Token | Value | Copy |
|---|---|---|---|
--nbhd-upload-dropzone-alignItems | — | center |
|
--nbhd-upload-dropzone-backgroundColor | — | transparent |
|
--nbhd-upload-dropzone-borderColor | --nbhd-context-color-control-border | Adapts to surface | |
--nbhd-upload-dropzone-borderRadius | --nbhd-border-radius-md | 6px |
|
--nbhd-upload-dropzone-borderStyle | — | dashed |
|
--nbhd-upload-dropzone-borderWidth | --nbhd-border-width-emphasis | 2px |
|
--nbhd-upload-dropzone-color | --nbhd-context-color-control-foreground | Adapts to surface | |
--nbhd-upload-dropzone-cursor | — | pointer |
|
--nbhd-upload-dropzone-disabled-cursor | — | not-allowed |
|
--nbhd-upload-dropzone-dragover-backgroundColor-opacity | — | 0.06 |
|
--nbhd-upload-dropzone-dragover-borderStyle | — | solid |
|
--nbhd-upload-dropzone-gap | --nbhd-space-3 | 12px |
|
--nbhd-upload-dropzone-minBlockSize | — | 140px |
|
--nbhd-upload-dropzone-paddingBlock | --nbhd-space-6 | 24px |
|
--nbhd-upload-dropzone-paddingInline | --nbhd-space-4 | 16px |
|
--nbhd-upload-dropzone-textAlign | — | center |
|
--nbhd-upload-dropzone-transitionDuration | --nbhd-motion-duration-normal | 0.2s |
|
--nbhd-upload-file-backgroundColor | --nbhd-context-color-control-background | Adapts to surface | |
--nbhd-upload-file-borderColor | --nbhd-context-color-control-border | Adapts to surface | |
--nbhd-upload-file-borderRadius | --nbhd-border-radius-sm | 2px |
|
--nbhd-upload-file-borderStyle | — | solid |
|
--nbhd-upload-file-borderWidth | --nbhd-border-width-subtle | 1px |
|
--nbhd-upload-file-color | --nbhd-context-color-control-foreground | Adapts to surface | |
--nbhd-upload-file-gap | --nbhd-space-3 | 12px |
|
--nbhd-upload-file-paddingBlock | --nbhd-space-2 | 8px |
|
--nbhd-upload-file-paddingInline | --nbhd-space-3 | 12px |
|
--nbhd-upload-fileList-gap | --nbhd-space-2 | 8px |
|
--nbhd-upload-gap | --nbhd-space-2 | 8px |
|
--nbhd-upload-host-display | — | block |
|
--nbhd-upload-icon-color | --nbhd-context-color-text-secondary | Adapts to surface | |
--nbhd-upload-icon-marginBlockEnd | — | 0.25rem |
|
--nbhd-upload-icon-size | --nbhd-size-icon-xxl | 48px |
|
--nbhd-upload-inlineSize | — | 100% |
|
--nbhd-upload-maxInlineSize | — | 100% |
|
--nbhd-upload-thumbnail-borderRadius | --nbhd-border-radius-sm | 2px |
|
--nbhd-upload-thumbnail-objectFit | — | cover |
|
--nbhd-upload-thumbnail-size | --nbhd-size-thumbnail | 56px |
No upload match.
Form control
| Property | Token | Value | Copy |
|---|---|---|---|
--nbhd-formControl-display | — | inline |
|
--nbhd-formControl-field-appearance | — | none |
|
--nbhd-formControl-field-borderRadius | --nbhd-border-radius-none | 0 |
|
--nbhd-formControl-field-color | --nbhd-context-color-control-foreground | Adapts to surface | |
--nbhd-formControl-field-display | — | inline-block |
|
--nbhd-formControl-field-fontFamily | --nbhd-typography-body-fontFamily | sans-serif |
|
--nbhd-formControl-field-fontSize | --nbhd-typography-body-fontSize | 1rem |
|
--nbhd-formControl-field-inlineSize | — | 100% |
|
--nbhd-formControl-field-position | — | relative |
|
--nbhd-formControl-fontFamily | --nbhd-typography-body-fontFamily | sans-serif |
|
--nbhd-formControl-host-display | — | block |
|
--nbhd-formControl-label-color | --nbhd-context-color-text-primary | Adapts to surface | |
--nbhd-formControl-label-display | — | block |
|
--nbhd-formControl-label-fontFamily | --nbhd-typography-label-fontFamily | sans-serif |
|
--nbhd-formControl-label-fontSize | --nbhd-typography-label-fontSize | 1rem |
|
--nbhd-formControl-label-fontWeight | --nbhd-typography-label-fontWeight | 600 |
|
--nbhd-formControl-label-letterSpacing | — | inherit |
|
--nbhd-formControl-label-marginBlock | --nbhd-space-0 --nbhd-space-05 | 0px 2px |
|
--nbhd-formControl-label-position | — | relative |
|
--nbhd-formControl-label-textTransform | — | inherit |
|
--nbhd-formControl-marginBlock | --nbhd-space-0 | 0px |
|
--nbhd-formControl-maxInlineSize | — | 100% |
|
--nbhd-formControl-paddingBlock | --nbhd-space-0 | 0px |
|
--nbhd-formControl-paddingInline | --nbhd-space-0 | 0px |
|
--nbhd-formControl-position | — | relative |
|
--nbhd-formControl-required-gap | --nbhd-space-05 | 2px |
|
--nbhd-formControl-text-marginBlock | --nbhd-space-1 --nbhd-space-0 | 4px 0px |
No form control match.
Dependencies
Child components <nbhd-upload> renders internally. Import them too when you tree-shake.