Previews
Preview providers control how Phials visualizes a file in the preview pane: optional thumbnail (grid), inline preview, and fullscreen. Each file resolves to at most one winning provider by priority and matching rules.
Types: PreviewProvider, PreviewAPI, FileMatchAPI in the same file.
Related: Plugin overview · Plugin API · Metadata
Mental model
thumbnail— small tile in grid views.preview— main preview pane.fullscreen— large / full-tab surface.
Any surface can be omitted. Components are Svelte Component<…> as in the type definition.
Matching files
The host indexes providers by extensions, mimeTypes, and categories (normalized). For each file it derives extension, MIME, and category (folder vs file categories).
Candidates are sorted by priority (higher first). The first that handles the file wins:
- If the provider defines
canHandle(file, api), it alone decides. The second argument isFileMatchAPI:matchesExtension,matchesMime,matchesCategory. Lists are not re-checked whencanHandleis present. - Otherwise the provider must match extension, MIME, or category against its declared sets.
Important: Preview has no global path for providers with empty extensions, mimeTypes, and categories. Such a provider is not indexed unless it appears under an index key — set at least one dimension (or use canHandle with indexing keys so candidates exist).
Priority
Higher priority wins among matches. Ship a low-priority fallback only when you intentionally cover broad categories (for example unknown/archive-like types).
Optional behavior
| Field | Role |
|---|---|
overridesDoubleClick | Host may route double-click to this preview instead of default open. |
isEditable | Whether an edit affordance is offered when metadata is available. |
getQuickActions | Header actions for the preview chrome. |
PreviewAPI
Extends the base plugin API with preview-oriented helpers (for example metadata read helpers, fullscreen navigation). Exact members are in sdk/plugin-types.generated.d.ts. invoke and any file reads still follow your manifest permissions — only declare what you need.
Minimal example
import MyThumb from "./MyThumb.svelte";
import MyPreview from "./MyPreview.svelte";
const myPreview: PreviewProvider = {
type: "preview",
id: "my.vendor.preview",
name: "My Preview",
priority: 50,
extensions: ["xyz"],
mimeTypes: ["application/x-my-format"],
categories: ["document"],
thumbnail: MyThumb,
preview: MyPreview,
};
export default function createPlugin(): PhialsPlugin {
return {
id: "my.vendor",
name: "My Plugin",
version: "0.1.0",
providers: [myPreview],
};
}Pitfalls
canHandlewithout indexing keys — provider never becomes a candidate; keepextensions,mimeTypes, orcategoriesnon-empty when usingcanHandlefor gating.PreviewAPImetadata helpers may not populate every extracted field; pair with metadata providers when you need richextracteddata.FileMatchAPI.matchesCategoryusesfile.category; combine withfile.is_dirwhen you need folder-specific behavior.