Hiyve Components - v1.0.0
    Preparing search index...

    Props for the FileManager component.

    Requirement: Must be used inside a <FileCacheProvider> component (which itself must be inside a <HiyveProvider>) for automatic state management.

    When used inside FileCacheProvider:

    • Files, folders, loading states, and callbacks are handled automatically
    • Only onFileOpen is required to handle file selection
    • Override props (files, folders, etc.) can be provided to customize behavior

    When used standalone (without FileCacheProvider):

    • All data props (files, folders, currentPath, isLoading, userId) are required
    • All callbacks (onNavigate, onFileOpen, onRefresh) are required
    // Context-connected usage (recommended)
    import { HiyveProvider } from '@hiyve/react';
    import { FileManager, FileCacheProvider } from '@hiyve/react-collaboration';

    function App() {
    return (
    <HiyveProvider generateRoomToken={getToken}>
    <FileCacheProvider>
    <FileManager
    onFileOpen={(file) => console.log('Opened:', file.fileName)}
    showToolbar
    showBreadcrumbs
    />
    </FileCacheProvider>
    </HiyveProvider>
    );
    }
    // Filtered view (only shows specific types, flat view)
    <FileManager
    filterFileTypes={['whiteboard']}
    onFileOpen={handleOpenWhiteboard}
    onSwitchToTab={handleTabSwitch}
    />
    // Standalone usage with explicit state management
    <FileManager
    files={files}
    folders={folders}
    currentPath={currentPath}
    isLoading={isLoading}
    userId={userId}
    onNavigate={handleNavigate}
    onFileOpen={handleFileOpen}
    onRefresh={handleRefresh}
    />
    interface FileManagerProps {
        activeScope?: FileScope;
        availableTabs?: string[];
        clientThumbnailMaxDimension?: number;
        colors?: Partial<FileManagerColors>;
        columns?: FileListColumn[];
        controlledViewerFile?: FileEntry | null;
        currentPath?: string;
        currentUserId?: string;
        customAction?: CustomToolbarAction | null;
        customContextActions?: CustomContextAction[];
        customFilters?: CustomToolbarFilter[];
        customViewers?: Partial<Record<string, CustomViewerRenderer>>;
        defaultFilterChip?: string;
        defaultSortColumn?: FileListColumn | null;
        defaultSortDirection?: SortDirection;
        defaultViewMode?: FileManagerViewMode;
        enableAudioPassthrough?: boolean;
        enableClientThumbnails?: boolean;
        enableDragDrop?: boolean;
        enableMarkers?: boolean;
        enableMultiSelect?: boolean;
        enableRegions?: boolean;
        enableSmartOpening?: boolean;
        fieldFormatters?: Partial<
            Record<FileListColumn, (file: FileEntry) => string>,
        >;
        fileNameFormatter?: (file: FileEntry) => string;
        files?: FileEntry[];
        filterChipPriority?: ResourceType[];
        filterChips?: { label: string; types?: ResourceType[] }[];
        filterFileTypes?: ResourceType[];
        folders?: FolderEntry[];
        getCommentCount?: (file: FileEntry) => number;
        getThumbnailUrl?: (file: FileEntry) => string | undefined;
        icons?: Partial<FileManagerIcons>;
        isDownloading?: boolean;
        isFileShared?: (file: FileEntry) => boolean;
        isLoading?: boolean;
        isRefreshing?: boolean;
        isRoomOwner?: boolean;
        isUploading?: boolean;
        isVisible?: boolean;
        labels?: Partial<FileManagerLabels>;
        onAddComment?: (fileId: string, content: string) => Promise<void>;
        onCopyPublicToPrivate?: (
            fileId: string,
            opts?: { location?: string },
        ) => Promise<FileEntry>;
        onCreateFolder?: (name: string, parentPath: string) => Promise<void>;
        onDelete?: (files: FileEntry[]) => Promise<void>;
        onDeleteComment?: (fileId: string, commentId: string) => Promise<void>;
        onDeleteFolder?: (folder: FolderEntry) => Promise<void>;
        onDownload?: (files: FileEntry[]) => Promise<void>;
        onEditComment?: (
            fileId: string,
            commentId: string,
            content: string,
        ) => Promise<void>;
        onFetchFileTypes?: () => Promise<string[]>;
        onFileCountChange?: (count: number) => void;
        onFileEdit?: (file: FileEntry) => void;
        onFileOpen?: (file: FileEntry) => void;
        onGetAttendees?: () => Promise<{ userId: string; userName?: string }[]>;
        onGetComments?: (fileId: string) => Promise<FileComment[]>;
        onGetFileUrl?: (file: FileEntry) => Promise<string>;
        onGetMarkers?: (
            fileId: string,
        ) => {
            authorId?: string;
            authorName?: string;
            color?: string;
            content: string;
            createdAt?: string;
            editedAt?: string;
            id: string;
            time: number;
        }[];
        onGetRegions?: (
            fileId: string,
        ) => {
            channelIdx?: number;
            content: string;
            end: number;
            id: string;
            start: number;
        }[];
        onMarkerAdd?: (
            fileId: string,
            marker: {
                authorId?: string;
                authorName?: string;
                color?: string;
                content: string;
                createdAt?: string;
                editedAt?: string;
                id: string;
                time: number;
            },
        ) => void;
        onMarkerChange?: (
            fileId: string,
            marker: {
                authorId?: string;
                authorName?: string;
                color?: string;
                content: string;
                createdAt?: string;
                editedAt?: string;
                id: string;
                time: number;
            },
        ) => void;
        onMarkerDelete?: (fileId: string, markerId: string) => void;
        onMove?: (files: FileEntry[], newLocation: string) => Promise<void>;
        onNavigate?: (path: string) => void;
        onPdfAnnotationLockChange?: (locked: boolean) => void;
        onPdfPageChange?: (page: number) => void;
        onRefresh?: () => void;
        onRegionChange?: (
            fileId: string,
            region: {
                channelIdx?: number;
                content: string;
                end: number;
                id: string;
                start: number;
            },
        ) => void;
        onRegionDelete?: (fileId: string, regionId: string) => void;
        onRename?: (file: FileEntry, newName: string) => Promise<void>;
        onScopeChange?: (scope: FileScope) => void;
        onSelect?: (selection: { fileId: string; filename: string }) => void;
        onShare?: (files: FileEntry[], userIds: string[]) => Promise<void>;
        onSwitchToTab?: (tabName: string, file: FileEntry) => void;
        onUpload?: (file: File, location: string) => Promise<void>;
        onViewerOpenChange?: (file: FileEntry | null) => void;
        onViewModeChange?: (mode: FileManagerViewMode) => void;
        pdfAnnotationAuthorId?: string;
        pdfAnnotationLockController?: boolean;
        pdfAnnotationLocked?: boolean;
        pdfControlsDisabled?: boolean;
        pdfEnableAnnotations?: boolean;
        pdfPage?: number;
        publicFiles?: FileEntry[];
        refresh?: number;
        renderProps?: FileManagerRenderProps;
        renderShareUserList?: (
            props: {
                availableUsers: { userId: string; userName?: string }[];
                files: FileEntry[];
                isDisabled: boolean;
                onToggleUser: (userId: string) => void;
                selectedUserIds: Set<string>;
            },
        ) => ReactNode;
        resolveDisplayName?: (userId: string, defaultName?: string) => string;
        resourceTabMapping?: {
            add?: Record<string, string>;
            remove?: string[];
            replace?: Record<string, string>;
        };
        resourceViewerTypes?: {
            add?: string[];
            remove?: string[];
            replace?: string[];
        };
        roomName?: string;
        rowExtras?: Record<string, (file: FileEntry) => ReactNode>;
        scopesAvailable?: FileScope[];
        showBothOwnedAndShared?: boolean;
        showBreadcrumbs?: boolean;
        showOnlySharedFiles?: boolean;
        showToolbar?: boolean;
        sortStorageKey?: string;
        styles?: Partial<FileManagerStyles>;
        sx?: SxProps<Theme>;
        thumbnailGenerators?: ThumbnailGenerator[];
        userId?: string;
        viewerVariant?: "inline" | "fullscreen";
        viewMode?: FileManagerViewMode;
    }
    Index

    Properties

    activeScope? availableTabs? clientThumbnailMaxDimension? colors? columns? controlledViewerFile? currentPath? currentUserId? customAction? customContextActions? customFilters? customViewers? defaultFilterChip? defaultSortColumn? defaultSortDirection? defaultViewMode? enableAudioPassthrough? enableClientThumbnails? enableDragDrop? enableMarkers? enableMultiSelect? enableRegions? enableSmartOpening? fieldFormatters? fileNameFormatter? files? filterChipPriority? filterChips? filterFileTypes? folders? getCommentCount? getThumbnailUrl? icons? isDownloading? isFileShared? isLoading? isRefreshing? isRoomOwner? isUploading? isVisible? labels? onAddComment? onCopyPublicToPrivate? onCreateFolder? onDelete? onDeleteComment? onDeleteFolder? onDownload? onEditComment? onFetchFileTypes? onFileCountChange? onFileEdit? onFileOpen? onGetAttendees? onGetComments? onGetFileUrl? onGetMarkers? onGetRegions? onMarkerAdd? onMarkerChange? onMarkerDelete? onMove? onNavigate? onPdfAnnotationLockChange? onPdfPageChange? onRefresh? onRegionChange? onRegionDelete? onRename? onScopeChange? onSelect? onShare? onSwitchToTab? onUpload? onViewerOpenChange? onViewModeChange? pdfAnnotationAuthorId? pdfAnnotationLockController? pdfAnnotationLocked? pdfControlsDisabled? pdfEnableAnnotations? pdfPage? publicFiles? refresh? renderProps? renderShareUserList? resolveDisplayName? resourceTabMapping? resourceViewerTypes? roomName? rowExtras? scopesAvailable? showBothOwnedAndShared? showBreadcrumbs? showOnlySharedFiles? showToolbar? sortStorageKey? styles? sx? thumbnailGenerators? userId? viewerVariant? viewMode?

    Properties

    activeScope?: FileScope

    Currently selected scope. Required when scopesAvailable has more than one entry.

    availableTabs?: string[]

    Available tabs for smart opening

    clientThumbnailMaxDimension?: number

    Longest edge of generated client-side thumbnails, in pixels. Ignored when enableClientThumbnails is false.

    320
    
    colors?: Partial<FileManagerColors>

    Custom colors for theming

    columns?: FileListColumn[]

    Columns to display in the file list

    controlledViewerFile?: FileEntry | null

    Externally control the inline FileViewer's open state. Pass a FileEntry to open the viewer for that file, null to close it. Leave undefined to keep the viewer fully uncontrolled (default).

    Useful for presenter-sync style flows where one client drives which file the rest of the room is viewing.

    currentPath?: string

    Current folder path (e.g., '/', '/Notes', '/Recordings/2024'). When inside FileCacheProvider, this is managed internally unless overridden.

    currentUserId?: string

    Current user ID (used to determine edit permissions on markers)

    customAction?: CustomToolbarAction | null

    Custom toolbar action

    customContextActions?: CustomContextAction[]

    Custom context menu actions for files (appended after built-in actions)

    customFilters?: CustomToolbarFilter[]

    Custom filter dropdowns rendered in the toolbar alongside search and sort

    customViewers?: Partial<Record<string, CustomViewerRenderer>>

    Custom viewer renderers for specific resource types. These are passed to FileViewer for rendering custom file types.

    defaultFilterChip?: string

    Label of the filter chip to select by default. When provided, this chip is active on mount instead of "All".

    defaultSortColumn?: FileListColumn | null

    Default sort column when neither a controlled value nor a stored preference exists. Falls back to 'name' when omitted. Useful for letting an app-level preference drive the initial sort across many FileManager instances without overriding a user's per-instance choice (which lives in sortStorageKey localStorage).

    defaultSortDirection?: SortDirection

    Default sort direction paired with defaultSortColumn. Falls back to 'asc' when omitted. Same precedence rule: per-instance localStorage wins, then this default, then the built-in fallback.

    defaultViewMode?: FileManagerViewMode

    Default view mode when uncontrolled

    'table'
    
    enableAudioPassthrough?: boolean

    Enable broadcasting media audio into a Hiyve room via the rtc-client audio merger. Forwarded to the inner FileViewerMediaFileViewerMediaPlayer. Consumers must mount the passthrough bridge (useMediaPassthroughBridge from @hiyve/react) once at room scope to route the resulting events to their client. The room/client must have been connected with enableAudioMerge: true.

    false
    
    enableClientThumbnails?: boolean

    Enable client-side thumbnail generation for card view.

    When true and onGetFileUrl is provided, card-view tiles lazily run a thumbnail generator for each file that enters the viewport and cache the resulting image in IndexedDB. Subsequent visits serve thumbnails from the cache with no network cost. Generation is serialized, so only one file downloads/renders at a time.

    Built-in generators cover images, videos/recordings, text-based resources (notes, assignments, transcripts), and a synthetic placeholder for everything except audio. Use thumbnailGenerators to add custom ones.

    file.thumbnailUrl and getThumbnailUrl take precedence when set.

    false
    
    enableDragDrop?: boolean

    Whether to enable drag-and-drop file moving

    true
    
    enableMarkers?: boolean

    Enable timeline markers for audio/video files

    false
    
    enableMultiSelect?: boolean

    Whether to enable multi-file selection

    true
    
    enableRegions?: boolean

    Enable region creation and loop playback for audio/video files

    false
    
    enableSmartOpening?: boolean

    Enable smart opening (open whiteboards/notes in their respective tabs)

    false
    
    fieldFormatters?: Partial<Record<FileListColumn, (file: FileEntry) => string>>

    Custom formatters for file list columns. Each key is a column name, and the value is a function that receives the file and returns a display string. The formatter's return value replaces the default cell text.

    <FileManager
    fieldFormatters={{
    roomName: (file) => roomAliasMap.get(file.roomName) || file.roomName,
    owner: (file) => userNameMap.get(file.userId) || file.userId,
    }}
    />
    fileNameFormatter?: (file: FileEntry) => string

    Custom file name formatter

    files?: FileEntry[]

    Array of files in current folder. When inside FileCacheProvider, this is derived from context unless overridden.

    filterChipPriority?: ResourceType[]

    Resource types to show first in auto-generated filter chips. Types not in this list appear after, sorted alphabetically. Only used when filterChips is not provided.

    filterChips?: { label: string; types?: ResourceType[] }[]

    Filter chip definitions to render between toolbar and content. When provided, a chip bar is shown allowing users to filter by resource type. The first chip is selected by default.

    <FileManager
    filterChips={[
    { label: 'All', types: undefined },
    { label: 'Whiteboards', types: ['whiteboard'] },
    { label: 'Notes', types: ['usernote', 'note'] },
    ]}
    />
    filterFileTypes?: ResourceType[]

    Filter to specific file types (forces flat view)

    folders?: FolderEntry[]

    Array of subfolders in current folder. When inside FileCacheProvider, this is derived from context unless overridden.

    getCommentCount?: (file: FileEntry) => number

    Return the number of comments on a file (for badge display on file rows/cards). When provided, files with count > 0 show a comment icon.

    getThumbnailUrl?: (file: FileEntry) => string | undefined

    Resolve a thumbnail/preview image URL for a file. When provided and returning a URL, card-view tiles render it as a banner at the top of the card. file.thumbnailUrl (when set on the entry) takes precedence.

    <FileManager
    getThumbnailUrl={(file) =>
    file.resourceType === 'image' ? buildPresignedUrl(file.s3Path) : undefined
    }
    />
    icons?: Partial<FileManagerIcons>

    Custom icons

    isDownloading?: boolean

    Whether download is in progress (managed internally when inside FileCacheProvider)

    isFileShared?: (file: FileEntry) => boolean

    Determine whether a file's "Shared" badge should appear on its row/card. When omitted, the badge shows whenever the file has any sharee (file.shared.length > 0). Override to scope by audience — e.g. inside a live room, hide the badge unless the file is actually shared with at least one current participant.

    isLoading?: boolean

    Whether files are currently loading. When inside FileCacheProvider, this is derived from context unless overridden.

    isRefreshing?: boolean

    Whether refresh is in progress (managed internally when inside FileCacheProvider)

    isRoomOwner?: boolean

    Whether current user is room owner (derived from context when inside FileCacheProvider)

    isUploading?: boolean

    Whether upload is in progress (managed internally when inside FileCacheProvider)

    isVisible?: boolean

    Whether the component is visible (for lazy loading)

    labels?: Partial<FileManagerLabels>

    Custom labels for internationalization

    onAddComment?: (fileId: string, content: string) => Promise<void>

    Add a new comment to a file

    onCopyPublicToPrivate?: (
        fileId: string,
        opts?: { location?: string },
    ) => Promise<FileEntry>

    Server-side clone a public file into the caller's private files (copy-on-write).

    Called when the user triggers copy/duplicate/move on a public file. Must return the newly-created private FileEntry. Typically cloudClient.copyFileToPrivate via usePublicFiles().copyToPrivate.

    onCreateFolder?: (name: string, parentPath: string) => Promise<void>

    Create a new folder

    onDelete?: (files: FileEntry[]) => Promise<void>

    Delete files

    onDeleteComment?: (fileId: string, commentId: string) => Promise<void>

    Delete a comment from a file

    onDeleteFolder?: (folder: FolderEntry) => Promise<void>

    Delete a folder

    onDownload?: (files: FileEntry[]) => Promise<void>

    Download a file or files

    onEditComment?: (
        fileId: string,
        commentId: string,
        content: string,
    ) => Promise<void>

    Edit a comment on a file

    onFetchFileTypes?: () => Promise<string[]>

    Get list of available file types for filtering

    onFileCountChange?: (count: number) => void

    Callback fired when the file count changes (useful for conditional UI)

    onFileEdit?: (file: FileEntry) => void

    Callback when a file should be opened in an editor (for types without inline viewers). If provided, prevents the fallback "no preview" viewer from opening.

    onFileOpen?: (file: FileEntry) => void

    Handle double-click to open file. This is always called when a file is opened.

    onGetAttendees?: () => Promise<{ userId: string; userName?: string }[]>

    Get attendees for sharing dialog

    onGetComments?: (fileId: string) => Promise<FileComment[]>

    Get comments for a specific file. When provided, enables the comments panel. Called when a file is selected and the comments panel is opened.

    onGetFileUrl?: (file: FileEntry) => Promise<string>

    Get presigned URL for file viewing

    onGetMarkers?: (
        fileId: string,
    ) => {
        authorId?: string;
        authorName?: string;
        color?: string;
        content: string;
        createdAt?: string;
        editedAt?: string;
        id: string;
        time: number;
    }[]

    Get saved timeline markers for a specific file

    onGetRegions?: (
        fileId: string,
    ) => {
        channelIdx?: number;
        content: string;
        end: number;
        id: string;
        start: number;
    }[]

    Get saved regions for a specific file

    onMarkerAdd?: (
        fileId: string,
        marker: {
            authorId?: string;
            authorName?: string;
            color?: string;
            content: string;
            createdAt?: string;
            editedAt?: string;
            id: string;
            time: number;
        },
    ) => void

    Called when a new timeline marker is added

    onMarkerChange?: (
        fileId: string,
        marker: {
            authorId?: string;
            authorName?: string;
            color?: string;
            content: string;
            createdAt?: string;
            editedAt?: string;
            id: string;
            time: number;
        },
    ) => void

    Called when a timeline marker is updated

    onMarkerDelete?: (fileId: string, markerId: string) => void

    Called when a timeline marker is deleted

    onMove?: (files: FileEntry[], newLocation: string) => Promise<void>

    Move file(s) to a new location

    onNavigate?: (path: string) => void

    Navigate to a folder path. When inside FileCacheProvider, this is auto-wired unless overridden.

    onPdfAnnotationLockChange?: (locked: boolean) => void
    onPdfPageChange?: (page: number) => void

    Fires when the inline PDF viewer's active page changes. The teacher's presenter-sync wiring listens here and rebroadcasts. Forwarded to FileViewerProps.onPdfPageChange.

    onRefresh?: () => void

    Refresh the file list. When inside FileCacheProvider, this is auto-wired unless overridden.

    onRegionChange?: (
        fileId: string,
        region: {
            channelIdx?: number;
            content: string;
            end: number;
            id: string;
            start: number;
        },
    ) => void

    Called when a named region is created or updated

    onRegionDelete?: (fileId: string, regionId: string) => void

    Called when a named region is deleted

    onRename?: (file: FileEntry, newName: string) => Promise<void>

    Rename a file

    onScopeChange?: (scope: FileScope) => void

    Called when the user changes scope via the selector.

    onSelect?: (selection: { fileId: string; filename: string }) => void

    Callback when a file is selected

    onShare?: (files: FileEntry[], userIds: string[]) => Promise<void>

    Share files with users

    onSwitchToTab?: (tabName: string, file: FileEntry) => void

    Callback when switching to a specific tab (for smart opening)

    onUpload?: (file: File, location: string) => Promise<void>

    Upload a file. Returns void or throws on error.

    onViewerOpenChange?: (file: FileEntry | null) => void

    Called whenever the inline FileViewer opens a new file or closes (local user action). Use this to broadcast the viewer state to other clients in a presenter-sync setup.

    onViewModeChange?: (mode: FileManagerViewMode) => void

    Callback when view mode changes

    pdfAnnotationAuthorId?: string
    pdfAnnotationLockController?: boolean
    pdfAnnotationLocked?: boolean
    pdfControlsDisabled?: boolean

    Hide the PDF toolbar and ignore page-navigation input. Lock followers to the presenter's page. Forwarded to FileViewerProps.pdfControlsDisabled.

    pdfEnableAnnotations?: boolean
    pdfPage?: number

    Controlled current page (1-based) for the inline PDF viewer. When set, the viewer scrolls to this page. Forwarded to FileViewerProps.pdfPage. Used by lesson presenter-sync to follow a teacher's page.

    publicFiles?: FileEntry[]

    File list used when activeScope === 'public-files'. Normally sourced from usePublicFiles() in the Muzie app.

    refresh?: number

    Trigger refresh from parent (increment to trigger refresh)

    Render props for advanced customization

    renderShareUserList?: (
        props: {
            availableUsers: { userId: string; userName?: string }[];
            files: FileEntry[];
            isDisabled: boolean;
            onToggleUser: (userId: string) => void;
            selectedUserIds: Set<string>;
        },
    ) => ReactNode

    Custom render function for the sharing dialog's user selection area. When provided, replaces the default checkbox user list in the share dialog.

    files is the set of files being shared, so consumers can filter the candidate-user list per the file's context (e.g. members of the file's classroom only).

    resolveDisplayName?: (userId: string, defaultName?: string) => string

    Resolve a userId to a friendly display name. Forwarded to the embedded FileViewer (and from there to the room-summary viewer) so teacher-assigned student nicknames, authenticated user profile names, etc. take precedence over server-stored placeholders. Lesson contexts should pass their app-level resolver here.

    resourceTabMapping?: {
        add?: Record<string, string>;
        remove?: string[];
        replace?: Record<string, string>;
    }

    Customize the mapping of resource types to sidebar tab names for smart opening. When a file is double-clicked and has no inline viewer, this mapping determines which tab to switch to via onSwitchToTab.

    // Add a custom resource type that opens in a "documents" tab
    <FileManager resourceTabMapping={{ add: { 'custom-doc': 'documents' } }} />

    // Remove a mapping so it falls through to the file viewer
    <FileManager resourceTabMapping={{ remove: ['whiteboard'] }} />

    // Replace the entire mapping
    <FileManager resourceTabMapping={{ replace: { notes: 'notes', whiteboard: 'board' } }} />
    resourceViewerTypes?: { add?: string[]; remove?: string[]; replace?: string[] }

    Override which resource types open in the inline FileViewer. By default, types like image, video, pdf, room-summary, etc. open in the viewer. Types not in this set (e.g., whiteboard, notes) route to tab switching instead.

    // Add a custom type to the viewer set
    <FileManager resourceViewerTypes={{ add: ['my-custom-type'] }} />

    // Remove a type so it routes to tab switching
    <FileManager resourceViewerTypes={{ remove: ['room-summary'] }} />

    // Replace the entire set
    <FileManager resourceViewerTypes={{ replace: ['image', 'video', 'pdf'] }} />
    roomName?: string

    Room name (derived from context when inside FileCacheProvider)

    rowExtras?: Record<string, (file: FileEntry) => ReactNode>

    Per-resource-type row extras. The renderer is called for every file of the given resourceType and its return value is shown inline in the file row's metadata line (alongside the date and owner). Return null/undefined to skip rendering for a specific file — useful when the value depends on data that may not yet be populated (e.g. an appData field written on save).

    <FileManager
    rowExtras={{
    'clip-composition': (file) => {
    const count = file.appData?.clipCount;
    return typeof count === 'number' ? `${count} clips` : null;
    },
    }}
    />
    scopesAvailable?: FileScope[]

    Which scopes are available to the current user.

    Supply both 'private-files' and 'public-files' to render the scope selector. A single-entry array renders the selected scope with no selector. An empty or omitted array falls back to the historical behavior (private files only, no selector).

    showBothOwnedAndShared?: boolean

    Whether to show both owned and shared files

    showBreadcrumbs?: boolean

    Whether to show breadcrumb navigation

    true
    
    showOnlySharedFiles?: boolean

    Whether to show only files shared with user

    showToolbar?: boolean

    Whether to show the toolbar

    true
    
    sortStorageKey?: string

    localStorage key for persisting sort state. When provided, sort column and direction are saved and restored across sessions.

    styles?: Partial<FileManagerStyles>

    Custom style values

    sx?: SxProps<Theme>

    MUI sx styling prop

    thumbnailGenerators?: ThumbnailGenerator[]

    Custom thumbnail generators, prepended to the SDK's built-in list.

    The first generator whose canHandle(file) returns true produces the thumbnail — so custom generators for app-specific file types (e.g. a clip composition whose first video clip should be used) win over the built-ins. Ignored when enableClientThumbnails is false.

    const clipCompositionGenerator: ThumbnailGenerator = {
    name: 'clip-composition',
    canHandle: (f) => f.resourceType === 'clip-composition',
    generate: async ({ file, getFileUrl, maxDimension }) => {
    const json = await fetch(await getFileUrl(file)).then((r) => r.json());
    const firstVideo = json.clips.find((c) => c.type === 'video');
    if (!firstVideo) return undefined;
    const videoUrl = await getFileUrl({ ...firstVideo });
    return generateVideoThumbnailFromUrl(videoUrl, maxDimension);
    },
    };
    userId?: string

    Current user's ID. When inside FileCacheProvider, this is derived from context unless overridden.

    viewerVariant?: "inline" | "fullscreen"

    FileViewer layout: 'fullscreen' covers viewport, 'inline' stays within parent

    'fullscreen'
    

    Controlled view mode (table or card). When provided, the component is controlled.