# File

## Overview

The file component is a native file picker that mirrors the input component's border, spacing, typography, and focus treatment while keeping the browser's built-in filename readout.

The pattern uses a wrapping native `<label>` and a native `<input type="file">`, with the chooser button styled through `::file-selector-button` and no component-specific classes.

## When to use

Use a file input when users need to choose a local document, image, or other file for upload.

## When not to use

Do not use a file input to collect a path, URL, or existing remote file, and do not treat its browser constraints as a replacement for server-side validation.

## Usage

```html
<label>
  <span data-role="label">Attachment</span>
  <input id="demo-file" type="file" required />
  <span data-role="message" data-invalid="Choose a file before continuing."></span>
</label>
```

Use this component when the user needs to upload a document, image, or other local file.

Keep the native file input in the DOM so browser file selection, keyboard behavior, and form submission continue to work normally.

Let the browser render the selected filename text. This component intentionally avoids JavaScript and does not replace the native file selection UI.

Wrap the visible label text in a `[data-role="label"]` element so required fields can render the red asterisk immediately after the label text.

For native validation, place a `[data-role="message"]` element directly after the input inside the same label and pair that with native constraints such as `required` or `accept`.

This component follows the same classless authoring approach as the text input component and should not require a named wrapper class.

## Behavior

Covered by [Playwright behavior tests](../../tests/e2e/forms-inputs.spec.js).

- FIL-001: The chooser button should align with the shared secondary button treatment so it feels consistent with the rest of the system, including the subtle brand hover surface.
- FIL-002: File input color changes should transition smoothly, with reduced-motion preferences disabling the transition.
- FIL-003: The overall control should use the same border, radius, padding, and focus treatment as the text input component.
- FIL-004: The filename text comes from the browser's native file input rendering and may vary slightly by engine.
- FIL-005: Validation feedback should appear only after user interaction by using `:user-invalid`.
- FIL-006: Disabled file inputs should communicate their state through muted text and disabled surfaces.
## Accessibility

- Keep the native `<input type="file">` focusable and available to assistive technology.
- Use a visible label so the purpose of the upload control is always clear.
- Do not hide or replace the browser's native filename feedback unless a documented accessible enhancement is required.
- Provide clear helper or error text when accepted file types, size limits, or count limits need explanation.

## Variables

| Variable | Type | Description |
| --- | --- | --- |
| `--file-action-padding-inline` | `<length>` | Sets --file-action-padding-inline so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-border-color` | `<color>` | Sets the file input wrapper border color; change it for validation states or when file controls need stronger container separation. |
| `--file-color-border-subtle` | `<color>` | Sets --file-color-border-subtle so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-color-error-strong` | `<color>` | Sets --file-color-error-strong so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-color-focus-ring` | `<color>` | Sets --file-color-focus-ring so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-color-primary` | `<color>` | Sets --file-color-primary so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-color-text` | `<color>` | Sets --file-color-text so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-color-text-accent` | `<color>` | Sets --file-color-text-accent so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-color-text-subtle` | `<color>` | Sets --file-color-text-subtle so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-control-border-width` | `<length>` | Sets --file-control-border-width so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-control-gap` | `<length>` | Sets --file-control-gap so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-control-min-height` | `<length>` | Sets --file-control-min-height so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-control-padding-block` | `<length>` | Sets --file-control-padding-block so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-control-padding-inline` | `<length>` | Sets --file-control-padding-inline so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-control-radius` | `<length>` | Sets --file-control-radius so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-focus-ring-size` | `<length>` | Sets --file-focus-ring-size so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-font-family-sans` | `Any` | Sets --file-font-family-sans so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-font-size` | `<length>` | Sets --file-font-size so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-font-size-caption` | `<length>` | Sets --file-font-size-caption so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-line-height` | `<number>` | Sets --file-line-height so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--file-message-color` | `<color>` | Sets helper and validation message text color for file inputs; change it when status messaging should read as neutral, subtle, or error. |
| `--file-space-inline` | `<length>` | Sets --file-space-inline so the component can default to shared theme or layout tokens while exposing an overrideable component API. |

## Depends On

- `--color-border-subtle`
- `--color-error-strong`
- `--color-focus-ring`
- `--color-primary`
- `--color-text`
- `--color-text-accent`
- `--color-text-subtle`
- `--font-family-sans`
- `--font-line-height-body`
- `--font-size`
- `--font-size-caption`
- `--layout-action-padding-inline`
- `--layout-control-border-width`
- `--layout-control-gap`
- `--layout-control-min-height`
- `--layout-control-padding-block`
- `--layout-control-padding-inline`
- `--layout-control-radius`
- `--layout-focus-ring-size`
- `--layout-space-inline`
