Pattern · Lists and Feeds
NewFile List SwiftUI Block
A files section: storage by type, sort and list or grid, uploads with progress, rename, share, move and delete, and Add.
The files section of a folder, project or storage screen. A storage card splits the used space by type, the toolbar sorts by name, date, size or kind and switches between list and grid, and Add opens the system file importer or photo picker. Uploads show progress and Cancel and land as files, and every file has Rename in place, Share, Move and a confirmed Delete.
- SwiftUI
- iOS 17.0+
- file-list
$199 once, every piece included. See how installing works · Sign in
01
What's included
SwiftUI source you own, built on Apple frameworks only.
- Used of total with a bar and legend split by type
- Sort by name, date, size or kind, in a list or a grid
- Uploads with progress and Cancel that land as files
- Rename in place, Share, Move and Delete with a confirmation
- Add through the file importer or the photo picker
02
Implementation notes
How it behaves, what it handles, and the decisions behind it.
A storage card at the top gives the used space as the block's one large figure ("18.4 GB of 50 GB"), the share used, a bar split by type in steps of the primary ink, and a legend with each type's size. Under it a toolbar sorts by Name, Date, Size or Kind, switches between a list and a grid, and Add opens a menu with Choose Files, which presents the system file importer, and Photo Library, which presents the photo picker; Add shows a spinner while your closure takes the picked files. Folders come first in every sort with their item count. In the list, each file shows its type symbol or thumbnail, its name, size and day, and an ellipsis menu; in the grid, a larger thumbnail with the name and size under it. Uploads in flight sit first with a thin progress bar, "Uploading 39.7 MB of 64 MB" and Cancel, and land as files when your model moves them into the folder. Every file has the same menu on a long press: Rename edits the name in place with its own working and failed states, Share opens the system share sheet through ShareLink, Move calls you, and Delete asks first in a confirmation dialog and dims the row while it works. An empty folder says so with an Add button, and passing nil shows grey shapes while the folder loads.
Notes
FileList(folder:uploads:initialSort:initialArrangement:onImport:onImportPhotos:onOpen:onRename:onMove:onDelete:onCancelUpload:)takes the folder, the uploads and a closure per action you support; leave one out to hide its control. It is a section: no navigation stack, background, padding or scroll view of its own.FileList.Folderholds theitemsand an optionalStorage.Folder.sampleis the project folder from the preview.FileList.Itemhas anid,name,Kind(.folder,.image,.video,.audio,.document,.pdf,.spreadsheet,.presentation,.archive,.other),sizein bytes,modified,itemCountfor folders, an optionalthumbnailURL loaded withAsyncImage, and an optionalshareURLfor Share.summarygives the "2.4 MB · Oct 21" line.FileList.Uploadis anid,name,kind, bytessentandtotal. Update it as bytes go up; when it finishes, remove it and add itsItemto the folder, and the block moves it from one to the other.FileList.Storageisusedandtotalin bytes with up to fourSegments (label,bytes), largest first. Used space not covered by the segments joins the last one. Leavestoragenil to hide the card.Sortis.nameand.kindA to Z,.datenewest first and.sizelargest first.Arrangementis.listor.grid; the block keeps both as its own state from the initial values.onImportreceives security-scoped URLs fromfileImporter(any file type, several at once); callstartAccessingSecurityScopedResource()while you copy them.onImportPhotosreceivesPhotosPickerItems (images and videos, up to 20). Throwing from either shows itserrorDescriptionunder the toolbar.onRename(item, name)runs when the person submits the new name; the row shows a spinner, and a thrown error restores the old name with the message under it. Renaming from the grid switches to the list first.onDeleteruns after the person confirms. The row dims with a spinner until your model removes the item; a thrown error shows under it.onOpenis called when a file or folder is tapped;onMovewhen Move is chosen, for your folder picker;onCancelUploadfrom an upload's Cancel.- Haptics mark a selection when the sort or the arrangement changes, success when a rename or delete finishes, and an error when anything fails.
- VoiceOver reads the storage card as one sentence with each type's size, each file as its name with size and day, uploads with their percentage, and announces renames and deletions.
- Reduce Motion turns every change into a short fade.
FileListExampleat the end ofFileList.swiftis the Files screen in the preview: a website project on a 50 GB plan where a zip of site photos finishes uploading and lands as a file. PasswrapsInNavigationStack: falseto push it in your own stack.
Theming
- Reads
SPThemefrom@Environment(\.spTheme)and requires thedesign-systemitem. - Cards are
color.surfacewithradius.lg, list rows at least 64 points withSPHairlinedividers inseparatorinset to the name, and groups 24 points apart (space.xl). - The used figure is the block's one display moment: the brand's display face (
type.face) at 28 points,type.numeralWeightcapped at semibold, monospaced digits. Other text usestype.subhead,type.body,type.footnoteandtype.captionintextPrimary,textSecondaryandtextTertiary. - The storage bar and the legend dots are
textPrimaryat full, 55%, 30% and 16% on afilltrack; upload bars aretextPrimaryonfill. - Type symbols sit on
fillsquares atradius.smin the list andradius.mdin the grid, intextSecondary. - Sort is a
surfacecapsule with aseparatorstroke; the List and Grid switch is afilltrack with the selection onsurfaceElevated. Add is the oneaccentcontrol, withaccentOntext. Errors aredanger. - Changes animate with
motion.smoothandmotion.snappy, and become short fades under Reduce Motion.
03
Keep building
Pieces that work well next to this one.