FileInput
FileInput enables users to select files from their device's file system for upload or processing. It combines a text field displaying selected files with a customizable button that opens the system file browser. Use it for forms, media uploads, and document processing workflows.
Key features:
- Drag and drop: Drop files directly onto the input or use the file browser
- File type filtering: Restrict selection to specific file types using
acceptsFileType - Multiple file selection: Enable users to select multiple files simultaneously
- Directory selection: Allow folder selection instead of individual files
- Customizable button: Configure button text, icons, position, and styling to match your design
Behaviors
This component supports the following behaviors:
| Behavior | Properties |
|---|---|
| Animation | animation, animationOptions |
| Bookmark | bookmark, bookmarkLevel, bookmarkTitle, bookmarkOmitFromToc |
| Form Binding | bindTo, initialValue, noSubmit |
| Component Label | label, labelPosition, labelWidth, labelBreak, required, enabled, shrinkToLabel, style, readOnly |
| Publish/Subscribe | subscribeToTopic |
| Tooltip | tooltip, tooltipMarkdown, tooltipOptions |
| Validation | bindTo, required, minLength, maxLength, lengthInvalidMessage, lengthInvalidSeverity, minValue, maxValue, rangeInvalidMessage, rangeInvalidSeverity, pattern, patternInvalidMessage, patternInvalidSeverity, regex, regexInvalidMessage, regexInvalidSeverity, validationMode, verboseValidationFeedback |
| Styling Variant | variant |
Properties
acceptsFileType
An optional list of file types the input controls accepts provided as a string array.
<App>
<FileInput acceptsFileType="{['.txt', '.jpg']}" />
</App><App>
<FileInput acceptsFileType="{['.txt', '.jpg']}" />
</App>autoFocus
default: false
If this property is set to true, the component gets the focus automatically when displayed.
buttonIcon
The ID of the icon to display in the button. You can change the default icon for all FileInput instances with the "icon.browse:FileInput" declaration in the app configuration file.
<App>
<FileInput buttonIcon="drive" buttonLabel="Let there be drive" />
<FileInput buttonIcon="drive" />
</App><App>
<FileInput buttonIcon="drive" buttonLabel="Let there be drive" />
<FileInput buttonIcon="drive" />
</App>buttonIconPosition
default: "start"
This optional string determines the location of the button icon.
Available values: start (default), end
<App>
<FileInput buttonIcon="drive" buttonLabel="End" buttonIconPosition="end" />
</App><App>
<FileInput buttonIcon="drive" buttonLabel="End" buttonIconPosition="end" />
</App>buttonLabel
This property is an optional string to set a label for the button part.
This property is an optional string to set a label for the button part.
<App >
<FileInput />
<FileInput buttonLabel="I am the button label" />
</App><App >
<FileInput />
<FileInput buttonLabel="I am the button label" />
</App>buttonPosition
default: "end"
This property determines the position of the button relative to the input field.
Available values: start, end (default)
buttonSize
The size of the button (small, medium, large)
Available values:
| Value | Description |
|---|---|
xs | Extra small |
sm | Small |
md | Medium |
lg | Large |
xl | Extra large |
<App>
<FileInput buttonSize="lg" />
</App><App>
<FileInput buttonSize="lg" />
</App>buttonThemeColor
default: "primary"
The button color scheme (primary, secondary, attention)
Available values: attention, primary (default), secondary
<App>
<FileInput buttonThemeColor="secondary" />
</App><App>
<FileInput buttonThemeColor="secondary" />
</App>buttonVariant
The button variant to use
Available values: solid, outlined, ghost
<App>
<FileInput buttonLabel="outlined" buttonVariant="outlined" />
</App><App>
<FileInput buttonLabel="outlined" buttonVariant="outlined" />
</App>csvOptions
Configuration options for CSV parsing (used when parseAs="csv"). Supports all Papa Parse configuration options. Default options: { header: true, skipEmptyLines: true }. Common options include delimiter, header, dynamicTyping, skipEmptyLines, and transform.
Configuration options for CSV parsing (used when parseAs="csv"). Supports all Papa Parse configuration options.
Default options: { header: true, skipEmptyLines: true }
Common options:
delimiter: Column separator (default:",")header: First row contains column names (default:true)dynamicTyping: Auto-convert numbers and booleans (default:false)skipEmptyLines: Ignore empty rows (default:true)transform: Function to transform values during parsing
Click to save: sample-products-semicolon.csv. Then browse to sample-products-semicolon.csv.
Click to save: sample-products-semicolon.csv. Then browse to sample-products-semicolon.csv.
Click to save: sample-products-typed.csv. Then browse to sample-products-typed.csv.
Click to save: sample-products-typed.csv. Then browse to sample-products-typed.csv.
Note:
dynamicTyping: trueis not a default. It converts string values to numbers and booleans during parsing.
Click to save: sample-products-tsv.tsv. Then browse to sample-products-tsv.tsv.
Click to save: sample-products-tsv.tsv. Then browse to sample-products-tsv.tsv.
Click to save: sample-inventory.csv (5000 rows). Then browse to sample-inventory.csv.
Click to save: sample-inventory.csv (5000 rows). Then browse to sample-inventory.csv.
directory
default: false
This boolean property indicates whether the component allows selecting directories (true) or files only (false).
enabled
default: true
This boolean property value indicates whether the component responds to user events (true) or not (false).
initialValue
This property sets the component's initial value.
multiple
default: false
This boolean property enables to add not just one (false), but multiple files to the field (true). This is done either by dragging onto the field or by selecting multiple files in the browser menu after clicking the input field button.
<App>
<FileInput multiple="false" />
<FileInput multiple="true" />
</App><App>
<FileInput multiple="false" />
<FileInput multiple="true" />
</App>parseAs
Automatically parse file contents as CSV or JSON. When set, the onDidChange event receives an object { files: File[], parsedData: ParseResult[] } containing both the raw files and parsed data. Each ParseResult includes file, data (parsed rows), and optional error. When parseAs is set, acceptsFileType is automatically inferred (e.g., ".csv" or ".json") unless explicitly overridden. Empty files are handled gracefully, returning an empty data array.
Available values: csv, json
Automatically parse file contents as CSV or JSON. When set, the onDidChange event receives an object containing both the raw files and parsed data:
| Key | Value |
|---|---|
files | Array containing the original File objects |
parsedData | Array containing:
|
When parseAs is set, acceptsFileType is automatically inferred (.csv or .json) unless explicitly overridden.
Note: Empty files are handled gracefully, returning an empty
dataarray without error.
Click to save: sample-products.csv. Then drag it onto the input, or click Browse to select it.
Click to save: sample-products.csv. Then drag it onto the input, or click Browse to select it.
Click to save: sample-products.json. Then browse to sample-products.json.
Click to save: sample-products.json. Then browse to sample-products.json.
Note: JSON parsing automatically converts single objects to arrays. If your JSON file contains a single object
{...}, it will be wrapped as[{...}]for consistent handling.
Click to save: sample-config.json. Then browse to sample-config.json.
Click to save: sample-config.json. Then browse to sample-config.json.
Parsing Multiple Files
When using parseAs with multiple="true", the parsedData array contains results for each file.
<App var.results="{[]}">
<FileInput
parseAs="csv"
multiple="true"
onDidChange="result => results = result.parsedData"
/>
<List data="{results}" when="{results.length > 0}">
<Text value="{$item.file.name}: {$item.data.length} rows" when="{!$item.error}" />
<Text value="{$item.file.name}: {$item.error.message}" color="$color-danger-500" when="{$item.error}" />
</List>
</App><App var.results="{[]}">
<FileInput
parseAs="csv"
multiple="true"
onDidChange="result => results = result.parsedData"
/>
<List data="{results}" when="{results.length > 0}">
<Text value="{$item.file.name}: {$item.data.length} rows" when="{!$item.error}" />
<Text value="{$item.file.name}: {$item.error.message}" color="$color-danger-500" when="{$item.error}" />
</List>
</App><App var.successCount="{0}" var.failCount="{0}">
<FileInput
parseAs="csv"
multiple="true"
csvOptions="{{ dynamicTyping: true }}"
onDidChange="{result => {
successCount = result.parsedData.filter(r => !r.error).length;
failCount = result.parsedData.filter(r => r.error).length;
}}"
/>
<HStack when="{successCount + failCount > 0}">
<Text value="Success: {successCount}" color="$color-success-500" />
<Text value="Failed: {failCount}" color="$color-danger-500" />
</HStack>
</App><App var.successCount="{0}" var.failCount="{0}">
<FileInput
parseAs="csv"
multiple="true"
csvOptions="{{ dynamicTyping: true }}"
onDidChange="{result => {
successCount = result.parsedData.filter(r => !r.error).length;
failCount = result.parsedData.filter(r => r.error).length;
}}"
/>
<HStack when="{successCount + failCount > 0}">
<Text value="Success: {successCount}" color="$color-success-500" />
<Text value="Failed: {failCount}" color="$color-danger-500" />
</HStack>
</App>placeholder
An optional placeholder text that is visible in the input field when its empty.
readOnly
default: false
Set this property to true to disallow changing the component value.
required
default: false
Set this property to true to indicate it must have a value before submitting the containing form.
validationStatus
default: "none"
This property allows you to set the validation status of the input component.
Available values:
| Value | Description |
|---|---|
valid | Visual indicator for an input that is accepted |
warning | Visual indicator for an input that produced a warning |
error | Visual indicator for an input that produced an error |
Events
didChange
This event is triggered when value of FileInput has changed.
Signature: didChange(newValue: any): void
newValue: The new value of the component.
Write in the input field and see how the Text underneath it is updated in accordingly.
<App var.field="">
<FileInput onDidChange="(file) => field = file[0]?.name" />
<Text value="{field}" />
</App><App var.field="">
<FileInput onDidChange="(file) => field = file[0]?.name" />
<Text value="{field}" />
</App>gotFocus
This event is triggered when the FileInput has received the focus.
Signature: gotFocus(): void
Clicking on the FileInput in the example demo changes the label text.
Note how clicking elsewhere resets the text to the original.
<App>
<FileInput
buttonLabel="{focused === true ? 'I got focused!' : 'I lost focus...'}"
onGotFocus="focused = true"
onLostFocus="focused = false"
var.focused="{false}"
/>
</App><App>
<FileInput
buttonLabel="{focused === true ? 'I got focused!' : 'I lost focus...'}"
onGotFocus="focused = true"
onLostFocus="focused = false"
var.focused="{false}"
/>
</App>lostFocus
This event is triggered when the FileInput has lost the focus.
Signature: lostFocus(): void
(See the example above)
parseError
This event is triggered when file parsing fails. Receives the error and the file that failed to parse.
Signature: parseError(error: Error, file: File): void
error: The parsing error that occurredfile: The file that failed to parse
This event is triggered when file parsing fails (when using parseAs). If not provided, parse errors are logged to the console.
Signature: parseError(error: Error, file: File): void
error: The parsing error that occurredfile: The file that failed to parse
Click to save: sample-broken.csv. Then browse to sample-broken.csv.
Click to save: sample-broken.csv. Then browse to sample-broken.csv.
Click to save: sample-broken.json. Then browse to sample-broken.json.
Click to save: sample-broken.json. Then browse to sample-broken.json.
Exposed Methods
focus
This API command focuses the input field of the component.
Signature: focus(): void
<App>
<Button label="Focus FileInput" onClick="fileInputComponent.focus()" />
<FileInput id="fileInputComponent" />
</App><App>
<Button label="Focus FileInput" onClick="fileInputComponent.focus()" />
<FileInput id="fileInputComponent" />
</App>getFields
This method returns the column headers from the most recently parsed CSV file.
Signature: getFields(): string[] | undefined
Returns an array of column header names (available when parseAs="csv" and header: true, which is the default).
Click to save: sample-products.csv. Then browse to sample-products.csv.
<App var.products="{[]}">
<FileInput
id="csvInput"
parseAs="csv"
onDidChange="result => products = result.parsedData[0]?.data || []"
/>
<Text value="Columns: {csvInput.getFields()?.join(', ')}" when="{csvInput.getFields()}" />
<List data="{products}" when="{products.length > 0}">
<Text value="{$item.name}: ${$item.price}" />
</List>
</App><App var.products="{[]}">
<FileInput
id="csvInput"
parseAs="csv"
onDidChange="result => products = result.parsedData[0]?.data || []"
/>
<Text value="Columns: {csvInput.getFields()?.join(', ')}" when="{csvInput.getFields()}" />
<List data="{products}" when="{products.length > 0}">
<Text value="{$item.name}: ${$item.price}" />
</List>
</App>inProgress
This property indicates whether file parsing is currently in progress (when using parseAs).
Signature: get inProgress(): boolean
This property indicates whether file parsing is currently in progress (when using parseAs).
Signature: get inProgress(): boolean
Use this property to show loading indicators while files are being parsed. See the "Large file with loading spinner" example in the csvOptions section for usage.
<App var.data="{[]}">
<FileInput
id="csvInput"
parseAs="csv"
onDidChange="result => data = result.parsedData[0]?.data || []"
/>
<Text value="Parsing file..." when="{csvInput.inProgress}" />
<Text value="{data.length} rows loaded" when="{!csvInput.inProgress && data.length > 0}" />
</App><App var.data="{[]}">
<FileInput
id="csvInput"
parseAs="csv"
onDidChange="result => data = result.parsedData[0]?.data || []"
/>
<Text value="Parsing file..." when="{csvInput.inProgress}" />
<Text value="{data.length} rows loaded" when="{!csvInput.inProgress && data.length > 0}" />
</App>open
This API command triggers the file browsing dialog to open.
Signature: open(): void
<App>
<Button label="Open FileInput" onClick="fileInputComponent.open()" />
<FileInput id="fileInputComponent" />
</App><App>
<Button label="Open FileInput" onClick="fileInputComponent.open()" />
<FileInput id="fileInputComponent" />
</App>setValue
This method sets the current value of the component.
Signature: setValue(files: File[]): void
files: An array of File objects to set as the current value of the component.
value
This property holds the current value of the component, which is an array of files.
Signature: get value(): File[]
In the example below, select a file using the file browser of the FileInput component
and note how the Text component displays the selected file's name:
<App>
<Text value="Selected file name: {fileInputComponent.value}" />
<FileInput id="fileInputComponent" />
</App><App>
<Text value="Selected file name: {fileInputComponent.value}" />
<FileInput id="fileInputComponent" />
</App>Parts
The component has some parts that can be styled through layout properties and theme variables separately:
input: The file input area displaying selected file names.label: The label displayed for the file input.
Styling
The FileInput component does not theme variables directly.
However, it uses the Button and TextBox components under the hood.
Thus, modifying the styles of both of these components affects the FileInput.
See Button styling and TextBox styling.
Theme Variables
| Variable | Default Value (Light) | Default Value (Dark) |
|---|---|---|
| backgroundColor-FileInput--focus | none | none |
| borderColor-FileInput--focus | none | none |
| borderRadius-FileInput--focus | none | none |
| boxShadow-FileInput--focus | none | none |
| outlineColor-FileInput--focus | none | none |
| outlineOffset-FileInput--focus | none | none |
| outlineStyle-FileInput--focus | none | none |
| outlineWidth-FileInput--focus | none | none |
| textColor-FileInput--focus | none | none |