원클릭으로
file-input
Use when you need to upload and handle files.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use when you need to upload and handle files.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use when implementing help users understand their current location.
Use when implementing expand and collapse content sections.
Use when implementing user account configuration and preferences.
Use when implementing social activity and updates stream.
Use when implementing conversational AI chat interfaces.
Use when implementing handling AI-specific errors.
| name | file-input |
| description | Use when you need to upload and handle files. |
| metadata | {"id":"file-input","category":"forms","pattern":"File Input","source":"uxpatterns.dev","url":"https://uxpatterns.dev/patterns/forms/file-input","sourcePath":"apps/web/content/patterns/forms/file-input.mdx"} |
Upload and handle files
A File Input is a form component that allows users to select one or more files from their device's file system and upload them to a server. It ranges from the native <input type="file"> control to enhanced drop zones with drag-and-drop, file previews, upload progress indicators, and validation feedback.
File inputs appear in document management, profile photo upload, e-commerce product imagery, form attachment flows, and media-rich applications.
<input type="file" capture="environment"> or capture="user" to open the camera directly.references/pattern.md, then choose the smallest viable variation.| Key | Action |
|---|---|
Tab | Moves focus to the file input or drop zone |
Enter / Space | Opens the native file browser dialog |
Tab (in file list) | Moves focus to the next file item's remove button |
Enter / Space | Activates the focused remove button |
Delete | Removes focused file from the selection list (where implemented) |
Escape | Cancels an in-progress drag-and-drop operation |
URL.revokeObjectURL()The Problem: Validating file type by extension only on the client allows users (or malicious actors) to rename files and bypass restrictions.
How to Fix It? Validate both client-side (for UX) and server-side (for security).
// Client-side check (UX only)
function isValidFileType(file, accept) {
return accept.split(',').some(type => {
type = type.trim();
if (type.startsWith('.')) return file.name.endsWith(type);
if (type.endsWith('/*')) return file.type.startsWith(type.slice(0, -1));
return file.type === type;
});
}
# Server-side check (security-critical) — Python example
allowed_types = ['image/jpeg', 'image/png', 'application/pdf']
mime_type = magic.from_buffer(file_bytes, mime=True)
if mime_type not in allowed_types:
raise ValueError("Invalid file type")
The Problem: Users submit a form, see nothing happen for 30 seconds, and assume it is broken. They click submit again, causing duplicate uploads.
How to Fix It? Always show upload progress for uploads that will take more than 1 second.
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
progressBar.setAttribute('aria-valuenow', percent);
progressBar.style.width = `${percent}%`;
progressText.textContent = `${percent}%`;
}
});
The Problem:
A drop zone implemented as a <div> is not keyboard-accessible, excluding users who cannot use a mouse.
How to Fix It? Make the drop zone keyboard operable.
<!-- Good: keyboard-accessible drop zone -->
<div
class="file-input__dropzone"
role="button"
tabindex="0"
aria-label="Upload files. Press Enter or Space to open file browser."
>
<!-- ... -->
</div>
dropzone.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
fileInput.click();
}
});
For full implementation detail, examples, and testing notes, see references/pattern.md.
Pattern page: https://uxpatterns.dev/patterns/forms/file-input