Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

Attaches block plugin

One or more downloadable files with selectable presentation variants.

Install and register

npm install @shelamkoff/rector
import { 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.

Data

{
  "files": [{ "url": "https://cdn.example/a.pdf", "name": "a.pdf", "size": 1024, "extension": "pdf" }],
  "variant": "f"
}

Field reference

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.

Configuration

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.

Application file sources

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.

Capabilities

Multiple files; device upload and application sources; editable names; presentation variants; listener/object-URL cleanup; stale results are ignored after disposal.

Undo, lifecycle, and styles

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().

Document output

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.