Skip to content

Workspace tools

Task-specific tools: a file manager, a music studio and a collaborative canvas.

Installation & usage

npx @youj/cli add app-file-manager

Also installs app-page, async-button, badge, breadcrumb, button, checkbox, context-menu, counter, empty, icon-archive, icon-check, icon-cloud-upload, icon-copy, icon-download, icon-eye, icon-file, icon-file-text, icon-film, icon-folder, icon-image, icon-layout-grid, icon-layout-list, icon-link, icon-menu, icon-music, icon-search, icon-table, icon-trash, icon-upload, icon-x, illustrations, input-group, morph-label, presence-list, progress, resizable, select, sheet, skeleton, switch, toast, toggle-group, tree-view, typography, use-mobile, youj-core, youj-presets, youj-ui-core.

The CLI copies the block to blocks/app/file-manager.tsx with every component it uses, so it’s yours to edit.

Every prop is optional and falls back to the demo, so it renders as you see it until you pass your own. Give it your data, rewrite or translate its strings through copy, and connect its actions:

fileManager-view.tsx
'use client'

import { FileManager, type FileManagerProps } from '@/blocks/app/file-manager'

export function FileManagerView({ files, folders, storage }: Pick<FileManagerProps, 'files' | 'folders' | 'storage'>) {
  return (
    <FileManager
      files={files}
      folders={folders}
      storage={storage}
      copy={{ titleSuffix: ' files' }}
      onFolderChange={(folder) => {
        // your code
      }}
      onViewChange={(view) => {
        // your code
      }}
      onUpload={(file, folder, onProgress) => {
        // your code
      }}
    />
  )
}

Reference

Props28 props, 3 types

Props

FileManager props
PropType
themeThemeInput

A theme to force on the block. Default: none, so it inherits the app's (YoujProvider or a ThemeScope around it).

–
embeddedboolean

A page in your app's frame: the shared page header (AppPage) with search and Upload, and the frame's gutter, with no top bar of its own.

default true

true
brand{ name: string; logo?: ReactNode }

The product in the header, the breadcrumb root and the demo logo files.

default Stash

Stash
headingLevel1 | 2 | 3

The title's level.

default 1

1
copyPartial<FileManagerCopy>

Any of the block's strings, to rewrite or translate.

–
localestring

Formats dates and sizes. Default: copy.locale, else the app's locale (YoujProvider), else en-US.

–
filesFileManagerFile[]

Every file, each naming its folder by id. Uploads and deletes change the list from here.

default the demo's seventeen

the demo's seventeen
foldersFileManagerFolder[]

The folder tree.

default Brand, Campaigns (Autumn 26, Orbit launch), Contracts, Research

Brand, Campaigns (Autumn 26, Orbit launch), Contracts, Research
storageFileManagerStorage[]

What the storage meter splits the space used into.

default media, documents, archives

media, documents, archives
quotanumber

The storage quota, in bytes.

default 100 GB

100 GB
nowDate | number

The moment "Today" and "3 days ago" count from, in epoch ms.

default a fixed demo date

a fixed demo date
folderstring

The open folder, to control it. Pair with onFolderChange.

–
defaultFolderstring

The folder open at first, when uncontrolled. Default: Autumn 26 in the demo, else the first folder.

–
onFolderChange(folder: string) => void

Called with the folder's id when the person opens another.

–
view'grid' | 'list'

Grid or list, to control it. Pair with onViewChange.

–
defaultView'grid' | 'list'

Grid or list at first, when uncontrolled.

default 'grid'

'grid'
onViewChange(view: 'grid' | 'list') => void

Called when the person switches between grid and list.

–
onUpload(file: File, folder: string, onProgress: (percent: number) => void) => ReturnType<FileManagerUploadHandler>

Uploads one dropped or picked file into the open folder; report progress and resolve with the stored file. A rejection drops it from the tray with its message. Default: a demo transfer.

–
onDelete(files: FileManagerFile[]) => Promise<unknown> | unknown

Moves files to trash. They leave at once; a rejection puts them back and shows its message.

–
onRestore(files: FileManagerFile[]) => Promise<unknown> | unknown

Undo after a delete: the files are back in the list.

–
onDownload(files: FileManagerFile[]) => Promise<unknown> | unknown

Downloads one file (the preview) or the selection; resolve when it's done. Default: a demo wait.

–
onCopyLink(file: FileManagerFile) => Promise<unknown> | unknown

Copies a file's link (the tile's menu); resolve when copied. Default: a "Link copied" toast.

–
getShareUrl(file: FileManagerFile) => string

The share link the preview shows and copies. Default: a demo stash.app link.

–
onOpen(file: FileManagerFile) => void

Called when a file's preview opens.

–
loadingboolean

Shows skeleton tiles in place of the files while they load.

default false

false
errorReactNode

A load failure, shown in place of the files, with Try again when onRetry is set.

–
onRetry() => void

Called from the error's Try again button.

–
emptyReactNode

Replaces the empty folder's state. Default: a drop hint from copy.emptyTitle.

–

FileManagerFile

FileManagerFile props
PropType
idRequiredstring–
nameRequiredstring–
folderRequiredstring

The id of the folder it sits in.

–
kindRequiredKind
'image''video''doc''pdf''sheet''audio''archive'
–
sizeRequirednumber

In bytes.

–
modifiedRequirednumber

When it last changed, in epoch milliseconds.

–
ownerRequiredstring–
sceneScene

The scene that says what's inside. Default: its kind's.

–
preview'wordmark' | 'wordmark-inverse' | 'swatches'

Draws the content itself instead of a scene, for a file whose content is the point: a logo, a palette.

–
lengthstring

A clip's running time, shown on its tile.

–

FileManagerFolder

FileManagerFolder props
PropType
idRequiredstring–
nameRequiredstring–
childrenFileManagerFolder[]

Folders inside it, shown in the tree and as tiles above its files.

–

FileManagerStorage

FileManagerStorage props
PropType
labelRequiredstring–
bytesRequirednumber–
toneRequiredstring

The meter cells' background class, e.g. 'bg-accent'.

–
Strings57 keys for copy

Strings

copy takes any of these keys; the rest keep their defaults. A key whose text holds a value (a count, a name) takes a function.

titleSuffixsearchsearchPlaceholderuploadfoldersresizeFoldersstoragestorageOffilessortBysortModifiedsortNamesortSizeviewgridlistnoMatchTitlenoMatchDescriptionemptyTitleemptyDescriptionerrorTitleretrydropTopreviewselectdeselectselectFilecopyLinklinkCopiedcopieddeletemovedOnemovedManyundoactionFailedselectionselecteddownloaddownloadSelectedzippeddownloadeddeleteSelectedclearSelectionuploadsuploadinguploadingFileuploadFailedyoushareTitleshareSwitchlocationmodifiedownersizetodaykindslocale
Built from22 components
Accessibilitylandmarks, toolbars, status

Accessibility

File manager is a main under a header with labelled toolbar controls, a selection bar and an upload tray; the preview opens in a sheet that traps focus and closes with Escape, and file actions sit in menus with arrow-key navigation. Music studio’s controls are a labelled group and its arrangement is a labelled ordered list. Collaborative canvas is a main named by its board, with breadcrumbs, a labelled group of who is here and a Share button that reports the copied link; the board is the Whiteboard, its shapes a listbox walked with Tab, its cards regions of their own, and each comment pin a button that opens its thread in a popover that takes and returns focus. Links and buttons are real a and button elements with the kit’s focus ring.

Meeting booking is a main with time slots that use aria-pressed, field errors in an alert and the confirmation in a status region.