FileUpload
ui.widgets.FileUploadSélection de fichiers et zone de dépôt.
BEHAVIOR CONTRACT
Browse, la zone de dépôt, la liste de fichiers et le callback de l'app forment un seul état testable.
RECORDED INTERACTION
Le harness clique sur Browse… ; la story renseigne un chemin de fichier déterministe.
pub fn buildFileUpload(scope: *ui.Scope, cx: *ui.Cx) anyerror!*ui.Node {
const a = cx.allocator;
const c = try col(cx, 12);
const story = try cx.bindState(FileUploadStory, .{ .state = undefined });
const fu = try ui.widgets.FileUpload(.{
.width = 380,
.on_browse = cx.on(FileUploadStory, story, FileUploadStory.browse),
}, scope, cx);
story.state = fu.state;
fu.wrapper.meta.ownership.meta.test_id = "story.upload.wrapper";
// 拖放 drop zone:e2e 用 dragAt 往这块矩形里注入 entered/dropped
fu.state.drop_zone.meta.ownership.meta.test_id = "story.upload.dropzone";
try c.appendChild(a, fu.wrapper);
return c;
}Le code source tel quel de la story dans le Storybook (zenit 5f9add5+wip 2026-09-30). W désigne ui.widgets ; col / row / label sont de petits helpers de mise en page du Storybook.
FileUploadProps
ui.widgets.FileUploadfn mountFileUpload(props: FileUploadProps, scope: *Scope, cx: *Cx) !FileUploadMountChamp
Type
Défaut
Description
widthf32360—
max_filesusize8—
hint[]const u8"Click Browse to add files"—
on_browse?core.HandlerRefnullBrowse 按钮回调(宿主调起对话框后用 state.addFile 回填)。 null = 默认原生 NSOpenPanel(cx.openFilePanel)。
on_change?core.HandlerRefnull文件列表变化回调
FileUploadMount
ui.widgets.FileUploadChamp
Type
Défaut
Description
wrapper*Node—
—
state*FileUploadState—
—