file_picker_slider

file_picker_slider is a polished Flutter file picker widget for apps that need a familiar file-input experience on web and mobile, while still offering richer UI features such as previews, fullscreen image viewing, theming, and custom widget composition.

It is designed for real product flows such as profile images, product galleries, agreements, attachments, receipts, and other upload-driven screens.

Why use this package?

Flutter projects often need more than a bare file picker:

  • web should behave like a normal browser file input
  • mobile should feel natural for gallery and camera flows
  • selected files should be easy to consume in one cross-platform model
  • UI should be themeable instead of hardcoded
  • advanced teams should still be able to render their own custom picker widget

This package focuses on those gaps.

Highlights

  • Standard input-style picker UI by default
  • Single and multiple file selection
  • Optional preview panel
  • Fullscreen image viewer with overlay action icon
  • Mobile camera support for single-image flows
  • Web-safe AppFile result model
  • customBuilder support for fully custom UI
  • Theme extension support with FilePickerSliderThemeData
  • Works across Flutter platforms

Installation

Add the dependency:

dependencies:
  file_picker_slider: ^0.0.5

Then install packages:

flutter pub get

Platform setup

Android

No extra Android storage permissions are required for the package's default behavior.

  • file_picker handles the native picker flow
  • image_picker does not need legacy storage permissions for normal gallery use
  • avoid adding old storage permissions unless your app truly needs them

iOS

Because this package relies on file_picker and image_picker, your iOS app should include the following setup.

  1. Add use_frameworks! to ios/Podfile
target 'Runner' do
  use_frameworks!
  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
  1. Add usage descriptions to ios/Runner/Info.plist
<key>NSPhotoLibraryUsageDescription</key>
<string>We need photo library access to let users choose files and images.</string>
<key>NSCameraUsageDescription</key>
<string>We need camera access to let users capture an image.</string>

Optional iOS keys depending on your use case:

  • NSAppleMusicUsageDescription if you use FileType.audio
  • UIBackgroundModes with fetch and remote-notification if your document flow relies on cloud-backed files for FileType.any or FileType.custom

Web

No extra setup is required.

Important web note:

  • browser file picks do not provide a dependable local file path
  • use AppFile.fileBytes, AppFile.displayName, or AppFile.xFile
  • do not build web logic around filePath

macOS

If you support macOS, add user-selected file access entitlements to your macOS runner:

<key>com.apple.security.files.user-selected.read-only</key>
<true/>

Use the read/write entitlement instead if your app must also modify selected files.

Quick start

FilePickerWidget(
  allowMultiple: true,
  onFilePicked: (files) {
    for (final file in files) {
      debugPrint(file.displayName);
    }
  },
)

Returned file model

The widget returns List<AppFile> through onFilePicked.

Useful properties on AppFile:

  • displayName for UI labels
  • fileBytes for web uploads and in-memory handling
  • filePath for local/native path access when available
  • xFile for cross-platform interoperability
  • fileUrl for preloaded remote items
  • resolvedExtension and isImage for conditional UI logic

Common usage patterns

1. Standard picker with preview

FilePickerWidget(
  title: 'Product gallery',
  subtitle: 'Choose one or more product images.',
  allowMultiple: true,
  onFilePicked: (files) {
    // Save or upload files
  },
)

2. Input-only mode

If you want a cleaner file-input look without the preview panel:

FilePickerWidget(
  showPreview: false,
  onFilePicked: (files) {},
)

3. Custom widget UI

Use the built-in picking logic with your own UI:

FilePickerWidget(
  showPreview: false,
  onFilePicked: (files) {},
  customBuilder: (context, state) {
    return ListTile(
      title: Text(
        state.hasFiles ? state.activeFile!.displayName : 'Upload contract',
      ),
      trailing: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          if (state.canOpenFullscreen)
            IconButton(
              onPressed: () => state.openFullscreen!(),
              icon: const Icon(Icons.fullscreen_rounded),
            ),
          FilledButton(
            onPressed: () => state.openPicker(),
            child: const Text('Browse'),
          ),
        ],
      ),
      onTap: () => state.openPicker(),
    );
  },
)

4. Restrict file types

FilePickerWidget(
  type: FileType.custom,
  allowedExtensions: const ['pdf', 'doc', 'docx'],
  onFilePicked: (files) {},
)

5. Preload existing files

FilePickerWidget(
  initialFiles: <AppFile>[
    AppFile.network(url: 'https://example.com/cover.png'),
  ],
  onFilePicked: (files) {},
)

Platform behavior

Platform / flow Picker used
Web files and images file_picker
Android/iOS single image gallery image_picker.pickImage()
Android/iOS multiple images image_picker.pickMultiImage()
Android/iOS camera capture image_picker.pickImage(source: camera)
Documents, custom extensions, non-image files file_picker

Fullscreen preview

When preview is enabled and the active item is an image, the widget shows a fullscreen icon on the preview overlay. Users can:

  • open the image in fullscreen
  • swipe between multiple selected images
  • zoom and pan with InteractiveViewer

If you use customBuilder, the same capability is exposed through state.openFullscreen.

Theme customization

Customize the package with FilePickerSliderThemeData:

ThemeData(
  useMaterial3: true,
  extensions: <ThemeExtension<dynamic>>[
    const FilePickerSliderThemeData(
      accentColor: Color(0xFF0D9488),
      accentForegroundColor: Colors.white,
    ),
  ],
)

Notes

  • On mobile, camera support is intentionally limited to Android and iOS
  • On mobile image mode, gallery picking uses image_picker for a more natural native flow
  • On web, local file paths are unavailable by design
  • The example app in this package demonstrates both the default picker and a custom widget integration