controller
The state half of the generic Explorer. The `Z.fs.*` builders are stateless (data in, widgets out); this controller owns the VFS-backed navigation state and the callback routing that drives them, so both the Files panel and the save/load dialog reuse one model and one router.
controller
The state half of the generic Explorer. The Z.fs.* builders are stateless (data in, widgets out); this controller owns the VFS-backed navigation state and the callback routing that drives them, so both the Files panel and the save/load dialog reuse one model and one router.
It operates on a caller-owned slot table (so two Explorers — e.g. the panel and a dialog — keep independent state) and a caller-chosen callback prefix (so their widgets' callbacks don't collide). The controller caches directory listings, tracks the current directory, the expanded folder set, the selected path, and a file preview.
API
M.init(slot, opts?) -> slot— idempotently seed a controller state slot.opts.rootdefaults to/zero/.M.model(slot)— build the render model theZ.fs.explorer/Z.fs.dialogbuilders consume:{ root, currentDir, breadcrumbPath, treeRoots, listEntries, selectedPath, expanded, preview }.M.handle(slot, prefix, callbackId, data?) -> boolean— route an Explorer callback against this slot; returns true when handled.M.invalidate(slot, pathPrefix?)— drop cached listings underpathPrefix(or all when nil) so fresh writes show.M.readPreview(path) -> (text|nil, note, size)— read a file preview; refuses binary, truncates large text.M.confirmTarget(slot, mode, filename) -> path|nil— resolve the absolute target a dialog confirm should act on. In"save"mode it'scurrentDir .. filename(nil if filename is empty); in"open"mode it's the selected file (nil if nothing or a folder is selected).
Callback grammar
All callbacks carry the absolute path verbatim:
<prefix>-nav-<path>— breadcrumb segment<prefix>-tree-select-<path>— tree row<prefix>-tree-toggle-<path>— tree chevron<prefix>-list-<d|f>-<path>— details-list row (d= dir,f= file)<prefix>-up— parent directory<prefix>-refresh— drop cache for the visible subtree
Usage
local fsc = require("modules.zui.widget.fs.controller")
fsc.init(state.files, { root = "/zero/" })
local model = fsc.model(state.files)
local widget = Z.fs.explorer(model, { prefix = "files" })
-- in onCallback:
if fsc.handle(state.files, "files", callbackId, data) then end
Scoped to this part · feeds back into the world's score.