Skip to content

Add FileInput component to utah-design-system#562

Merged
steveoh merged 19 commits intomainfrom
copilot/add-file-input-component
Dec 1, 2025
Merged

Add FileInput component to utah-design-system#562
steveoh merged 19 commits intomainfrom
copilot/add-file-input-component

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Nov 21, 2025

Creating FileInput component for utah-design-system package

Implementation Plan:

  • Create FileInput.tsx component using react-aria-components FileTrigger and DropZone
    • Support single and multiple file selection
    • Support file type restrictions via accept prop with wildcard MIME type support (e.g., image/, video/)
    • Include drag-and-drop functionality with visual feedback
    • Display selected files with names and sizes
    • Include clear/remove functionality for selected files
    • Use Field components (Label, Description) for consistency
    • Apply proper focus ring and accessibility features
  • Create FileInput.stories.tsx with comprehensive examples
    • Basic single file selection
    • Multiple file selection
    • With file type restrictions (e.g., images, PDFs)
    • With validation (required field)
    • With description and error states
    • Disabled state
    • React Hook Form validation example
  • Export FileInput from index.ts
  • Verify TypeScript compilation
  • Run prettier formatting
  • Test the component in Storybook
  • Address all code review feedback
    • Notify parent component when files are removed or cleared
    • Use composite key (name + size + lastModified) for file list items for proper uniqueness
    • Replace div with AriaButton for FileTrigger child to fix click functionality
    • Add error handling for DataTransfer API (browser compatibility)
    • Add wildcard MIME type support (e.g., image/, video/) for file type filtering
    • Add ValidationResult support to errorMessage prop for consistency with other form components
  • Fix PressResponder warning by using proper pressable component
  • Remove TypeScript compiled output files that were accidentally committed
  • Implement drag and drop functionality using React Aria DropZone

Screenshots

FileInput Documentation in Storybook

Multiple Files Example

WRI Integration Example

Implementation Details

The FileInput component has been successfully implemented with the following features:

  • Component Structure: Built on top of react-aria-components' FileTrigger and DropZone for robust accessibility and drag-and-drop support
  • Visual Design: Styled with Tailwind CSS following Utah Design System conventions
  • File Selection: Supports both single and multiple file selection via allowsMultiple prop
  • File Type Restrictions: Accepts acceptedFileTypes prop to restrict file types with full wildcard MIME type support (e.g., image/* for all images, video/* for all videos, or specific types like image/png)
  • Drag and Drop: Full drag-and-drop support with visual feedback (border and background highlight) when files are dragged over the drop zone
  • File List Display: Shows selected files with names, sizes, and individual remove buttons with tooltips
  • Clear All: Button to clear all selected files at once
  • Form Integration: Works with HTML validation and React Hook Form
  • Parent Notification: Properly notifies parent component via onSelect callback when files are added, removed, or cleared
  • Validation States: Supports required, disabled, and invalid states with error messages
  • Error Messages: Supports both string and ValidationResult function forms for consistency with other form components (TextField, TextArea, etc.)
  • Accessibility: Full keyboard navigation and ARIA support through react-aria-components
  • Browser Compatibility: Includes error handling for environments where DataTransfer API may not be available
  • Click Functionality: Uses proper pressable Button component for FileTrigger interaction

All 12 story examples are working correctly in Storybook, demonstrating various use cases and states.

Security Summary

No security vulnerabilities were found during CodeQL analysis.

Original prompt

This section details on the original issue you should resolve

<issue_title>New Utah-Design-System Component: FileInput</issue_title>
<issue_description>Create a new component within the utah-design-system package that satisfies the following design document: https://designsystem.utah.gov/library/components/forms/fileInput. The code samples in this document are just an example of how it could be implemented and do not need to be followed exactly. Ignore the css classes in this doc and instead use tailwind.

Follow the conventions of other components in the utah-design-system package. Make sure to create stories for each of the different states.</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Add FileInput component to utah-design-system Add FileInput component to utah-design-system Nov 21, 2025
Copilot AI requested a review from stdavis November 21, 2025 18:10
@stdavis
Copy link
Copy Markdown
Member

stdavis commented Nov 21, 2025

@copilot When I click on the upload area, nothing happens and I get this warning in the console: PressResponder.tsx:45 A PressResponder was rendered without a pressable child. Either call the usePress hook, or wrap your DOM node with component.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Nov 21, 2025

@copilot When I click on the upload area, nothing happens and I get this warning in the console: PressResponder.tsx:45 A PressResponder was rendered without a pressable child. Either call the usePress...

Fixed in commit 4ac30a7. The issue was that FileTrigger requires a pressable child component (like a Button) to handle click interactions. I replaced the plain div with Button from react-aria-components, which properly implements the press interaction pattern. The upload area is now clickable and the warning is resolved.

@stdavis
Copy link
Copy Markdown
Member

stdavis commented Nov 21, 2025

@copilot You inadvertantly added the tsc .js output files. Please remove them.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Nov 21, 2025

@copilot You inadvertantly added the tsc .js output files. Please remove them.

Removed in commit 32a1c98. Deleted 102 .js files and 2 .tsbuildinfo files that were TypeScript compilation outputs. Also updated .gitignore to prevent these files from being tracked in the future by adding patterns for:

  • packages/utah-design-system/**/*.js
  • packages/utilities/**/*.js
  • vite.config.js
  • *.tsbuildinfo

@stdavis
Copy link
Copy Markdown
Member

stdavis commented Nov 21, 2025

@copilot Drag and drop isn't working. Please implement this: https://react-spectrum.adobe.com/react-aria/dnd.html

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Nov 21, 2025

@copilot Drag and drop isn't working. Please implement this: https://react-spectrum.adobe.com/react-aria/dnd.html

Implemented in commit 1c009dd. Added drag and drop functionality using React Aria's DropZone component:

  • Files can now be dragged and dropped onto the upload area
  • Visual feedback when dragging files over the drop zone (border turns primary color and background highlights)
  • Dropped files are filtered by acceptedFileTypes and allowsMultiple settings
  • The drop zone wraps the existing FileTrigger button so both click and drag-and-drop work seamlessly

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Nov 25, 2025

Visit the preview URL for this PR (updated for commit 3a625c1):
Firebase Preview: https://ut-dts-agrc-kitchen-sink-dev--copilot-add-file-input-c-c8pqgjmy.web.app
(expires "2025-12-15T22:10:27.559457674Z" )

@stdavis stdavis marked this pull request as ready for review November 25, 2025 19:38
Copilot AI review requested due to automatic review settings November 25, 2025 19:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new FileInput component to the utah-design-system package, implementing file upload functionality with drag-and-drop support, file type restrictions, and validation capabilities.

Key Changes

  • Implemented FileInput component using react-aria-components' FileTrigger and DropZone with full accessibility support
  • Added comprehensive Storybook stories demonstrating various states and use cases including React Hook Form integration
  • Updated build configuration to properly handle TypeScript compiled output

Reviewed changes

Copilot reviewed 4 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/utah-design-system/src/components/FileInput.tsx New FileInput component with drag-and-drop, file selection, and validation features
packages/utah-design-system/src/components/FileInput.stories.tsx Comprehensive Storybook stories for all FileInput states and use cases
packages/utah-design-system/src/index.ts Export FileInput component from package entry point
.gitignore Added TypeScript compiled output patterns to prevent committing generated files
package-lock.json Updated MSW optional dependency metadata with dev flags
public/mockServiceWorker.js Auto-generated MSW service worker update (v2.10.2 → v2.12.2)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@stdavis stdavis requested a review from steveoh November 25, 2025 19:52
@stdavis
Copy link
Copy Markdown
Member

stdavis commented Nov 25, 2025

@steveoh What do you think about this? I think that it's pretty good but I'm not sure that it's great yet.

@stdavis stdavis enabled auto-merge (rebase) November 25, 2025 19:53
@stdavis stdavis force-pushed the copilot/add-file-input-component branch from 77743aa to a0faffa Compare November 25, 2025 19:57
Copilot AI and others added 3 commits November 25, 2025 13:01
…DropZone

- Added DropZone component from react-aria-components to enable drag and drop
- Implemented handleDrop function to process dropped files
- Added visual feedback with isDropTarget state (border and background color change)
- Files are filtered by acceptedFileTypes and allowsMultiple settings
- Drop zone highlights when files are dragged over it

Co-authored-by: stdavis <1326248+stdavis@users.noreply.github.com>
@stdavis stdavis force-pushed the copilot/add-file-input-component branch from a0faffa to 373eee2 Compare November 25, 2025 20:01
also moved the description to where the dts uds has it
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 5 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@stdavis
Copy link
Copy Markdown
Member

stdavis commented Dec 1, 2025

I think that this is looking pretty good! Here's what it might look like in WRI:
image

steveoh and others added 2 commits December 1, 2025 13:09
Co-authored-by: Scott Davis <stdavis@utah.gov>
- Implemented matchesAcceptedType function to support wildcard MIME types (e.g., image/*, video/*)
- Updated handleDrop to use wildcard matching for file type filtering
- Added ValidationResult support to errorMessage prop type for consistency with other form components
- Error message can now be a function that receives ValidationResult parameter

Co-authored-by: steveoh <325813+steveoh@users.noreply.github.com>
auto-merge was automatically disabled December 1, 2025 21:06

Head branch was pushed to by a user without write access

@steveoh steveoh merged commit deaeb8e into main Dec 1, 2025
7 checks passed
@steveoh steveoh deleted the copilot/add-file-input-component branch December 1, 2025 22:09
@ugrc-release-bot ugrc-release-bot bot mentioned this pull request Dec 1, 2025
@ugrc-release-bot ugrc-release-bot bot mentioned this pull request Feb 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New Utah-Design-System Component: FileInput

4 participants