One or more downloadable files with selectable presentation variants.
npm install @shelamkoff/rectorimport { createEditor } from '@shelamkoff/rector'
import { Attaches } from '@shelamkoff/rector/plugins/attaches'
const editor = createEditor({
holder: document.querySelector('#editor'),
plugins: [new Attaches()],
})The registered block type is attaches. The class is also exported by the complete @shelamkoff/rector/plugins preset and can be loaded through @shelamkoff/rector/plugins/async.
{
"files": [{ "url": "https://cdn.example/a.pdf", "name": "a.pdf", "size": 1024, "extension": "pdf" }],
"variant": "f"
}| Field | Required | Meaning and constraints |
|---|---|---|
files |
yes | Non-empty array. Saves always use this plural form. |
files[].url |
yes | Canonical URL allowed by the download policy. |
files[].name, files[].extension |
yes | Strings used for the displayed file name and extension. |
files[].size |
yes | Finite non-negative byte count. |
variant |
no | Presentation variant a, b, f, or g; the plugin default is f. |
Legacy input may contain one file object instead of files; the next save normalizes it to the array contract. Callback URLs must pass the shared download URL policy. Without uploadFile, selected files use temporary object URLs; configure an uploader for data that must survive cleanup or page reload.
Every built-in block plugin accepts two style ownership options: injectStyles?: boolean defaults to true; set it to false when the host bundles that plugin's CSS. css?: string adds one host-provided stylesheet URL after the plugin default, or acts as the replacement URL when default injection is disabled.
uploadFile?: (file: File, context: { signal: AbortSignal }) => Promise<{ url: string; size?: number }> persists a selected browser file. actions?: Array<{ icon?; label; handler({ signal }): Promise<Array<{ url; name; size?; extension? }> | null> }> adds application file sources such as a media library. Both callbacks must respect the supplied abort signal.
Use uploadFile for browser File objects and actions for existing downloads selected from a file library, cloud drive, or another application-owned catalog. An action may return several files in one selection.
const attaches = new Attaches({
actions: [{
label: 'File library',
async handler({ signal }) {
const assets = await openFileLibrary({ multiple: true, signal })
return assets?.map(asset => ({
url: asset.downloadUrl,
name: asset.name,
size: asset.size,
extension: asset.extension,
})) ?? null
},
}],
})url and name are required. size and extension are optional; the extension is inferred from name when omitted. Return null when selection is cancelled. The complete selection becomes one undo/redo step. See File sources and media libraries for upload, cancellation, validation, and reusable adapter guidance.
Multiple files; device upload and application sources; editable names; presentation variants; listener/object-URL cleanup; stale results are ignored after disposal.
User actions exposed by the plugin enter the command pipeline through the supplied context.mutate() capability, so each completed action is one undo/redo step. The editor reference-counts the plugin's declared stylesheet URLs. Removing a block calls its cleanup hook; removing the editor calls destroy() for every remaining block and then releases shared plugin resources.
Do not remove the editor holder without first calling editor.destroy().
Use the matching renderer from @shelamkoff/rector/renderer/renderers/attaches. The VitePress guide documents configuration, commands and history, extension contracts, document migrations, styling, security, and lifecycle in a sequential form.