Skip to content

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 → UI

The 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.

Terminal window
pnpm add @eidos.space/eidos-file@2.0.0 \
@eidos.space/eidos-file-ui@2.0.0 react react-dom

Import the stylesheet once:

import "@eidos.space/eidos-file-ui/styles.css"

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.

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.

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:

  1. Host-resolved image thumbnail;
  2. trusted media-family icon or generic file icon;
  3. 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.

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 AssetLease issuance, 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.