Build with Eidos File UI
@eidos.space/eidos-file-ui@2.0.0 is the published React presentation layer
for the frozen Eidos UI 1.0 contract. The interoperable dependency path is:
Eidos File → Runtime → Adapter / HostServices → UIThe reusable UI package never receives SQLite, SQL, File bytes, native handles,
or ambient paths. Filtering, Formula, Lookup, Relation, grouping, validation,
and mutation semantics remain in @eidos.space/eidos-file Runtime.
Install
Section titled “Install”pnpm add @eidos.space/eidos-file@2.0.0 \ @eidos.space/eidos-file-ui@2.0.0 react react-domImport the stylesheet once:
import "@eidos.space/eidos-file-ui/styles.css"Exact viewer composition
Section titled “Exact viewer composition”The host application implements HostServices. openSource returns the only
RuntimeClient the UI consumes. EidosUIKernel negotiates both contracts,
loads the revision-bound schema, and owns page/cursor invalidation.
import { useEffect, useMemo } from "react"import type { HostServices } from "@eidos.space/eidos-file"import { EidosUIKernel } from "@eidos.space/eidos-file-ui/kernel"import { EidosStandardView, EidosUIRuntimeProvider,} from "@eidos.space/eidos-file-ui/runtime-platform"import "@eidos.space/eidos-file-ui/styles.css"
export function ProjectView({ host, sourceToken, assetPresenter }) { const kernel = useMemo(() => new EidosUIKernel(host), [host])
useEffect(() => { void kernel.openSource({ sourceToken, access: "read" }) return () => void kernel.close() }, [kernel, sourceToken])
return ( <EidosUIRuntimeProvider kernel={kernel} assetPresenter={assetPresenter} themeName="light" > <EidosStandardView /> </EidosUIRuntimeProvider> )}EidosStandardView renders standard Grid, Gallery, and Kanban views from
bounded Runtime results. Unknown namespaced view types remain preserved and
render as unsupported until the embedding application supplies an isolated
renderer.
Shared editor composition
Section titled “Shared editor composition”EidosStandardView is the read-only viewer composition. Browser and Desktop
use EidosFileEditorShell as the shared editor layout owner for View tabs,
query controls, Fields, the data canvas, Table tabs, and editor overlays.
import { EidosFileEditorShell } from "@eidos.space/eidos-file-ui/eidos-file-editor-shell"
const editor = ( <EidosFileEditorShell viewTabs={<EidosFileViewTabs {...viewTabs} />} queryToolbar={<EidosFileQueryToolbar {...query} />} fields={<EidosFileViewFieldsPopover {...fields} />} fieldCreator={<EidosFileFieldCreatePopover {...fieldCreator} />} sheetTabs={<EidosFileSheetTabs {...sheets} />} > <EidosFileEditorView source={source} table={table} view={view} /> </EidosFileEditorShell>)The named controls above are composition supplied by the host. Browser file pickers, Desktop filesystem integration, save/conflict handling, version history, and extension processes remain Host responsibilities.
File fields and assets
Section titled “File fields and assets”A File cell is an ordered array of complete FileEntry objects. Its uri is
one of: a relative URI-reference scoped to the directory containing the open
.eidos file, an absolute https: URI, or a canonical inline image Data URL.
The UI never joins, fetches, or navigates that URI.
For a visible image, UI calls HostServices.resolveAsset with the entry ID and
thumbnail purpose. It passes the returned lease only to the injected
AssetPresenter. Open and download are explicit user actions using preview
or download leases. Every lease is size/expiry/session bounded and released
when its surface disappears.
DOM cards use AssetPresenter.renderImage. The Canvas-backed Grid uses the
optional AssetPresenter.loadImage, redraws after decode, and releases leases
outside its bounded visible-row window. Without that method Grid falls back;
it never draws from the canonical URI directly.
The deterministic fallback is:
- Host-resolved image thumbnail;
- trusted media-family icon or generic file icon;
- inert, lossless URI display/copy text.
Ordinary URL fields remain inert and are never fetched because a cell is
visible. Hosts without a session-scoped relative asset root omit relative
from assetReadSchemes; they must not fall back to the application origin,
working directory, or downloads folder. SVG and other active content require a
Host-isolated presenter and must not be rendered unsandboxed.
Asset import follows the reverse boundary: composition obtains an opaque source
token, calls HostServices.acquireAsset, and submits the returned FileEntry
unchanged in a Runtime mutation. UI may reorder or remove whole entries, but it
does not manufacture IDs, URIs, media types, or sizes.
Host responsibilities
Section titled “Host responsibilities”The embedding application owns:
- source/destination grants, permissions, save/CAS, conflicts, and recovery;
- Browser Worker or Desktop IPC transport and Runtime replacement;
- truthful capabilities and limits for relative, Data URL, and HTTPS assets;
- purpose-scoped
AssetLeaseissuance, presentation, activation, and release; - isolation, traversal/symlink/origin checks, media/decode limits, and network policy.
Keep SQLite and expensive work outside React. Preserve unknown schema/view extensions. Test cancellation, replacement epochs, read-only behavior, keyboard focus, narrow layouts, asset expiry, all three File URI classes, and zero direct URI fetch/navigation.
EidosFileUIProvider supports locale="en" and locale="zh", plus host
message overrides. Locale affects presentation only; user-authored table,
field, view, option, and record names remain File data.