Skip to content

v0.21.0

Choose a tag to compare

@orkhanahmadov orkhanahmadov released this 29 Jul 10:40
Immutable release. Only release title and notes can be modified.
207e0ce

Features

Open-source Saved Blocks — reusable groups of blocks users save and re-insert — backed by a consumer-supplied storage provider. Previously Cloud-only ("Saved Modules").

@templatical/core · @templatical/editor · @templatical/types

The editor owns the UI; you own persistence. Templatical Cloud now consumes the same interface as one adapter rather than a separate implementation.

Saving starts from a block's bookmark action and opens a pick session: plain clicks add or remove blocks on the canvas, a bar shows the count with Save/Cancel (Escape cancels, Enter confirms), and Save opens a dialog that asks for a name and previews the picked blocks. The preview lists them in pick order and each row can be dragged (or moved with the arrow keys from its grip handle) to reorder before saving; blocks are stored in whatever order the list ends in. Picking never touches the editor's block selection. Browsing gives search, an optional free-text category filter, live preview, insert-at-position, rename and delete. A category is set in the save dialog (suggesting the ones already in use) and editable inline afterwards; it is flat and optional — there are no folders. Both filters run in the editor over whatever list() returned, so a provider that simply returns its entries gets search and categories for free.

Permissions are the implementer's to set. Each mutation on the provider is false | fn: pass false and the editor hides that affordance rather than letting the user try and fail. For exceptions on individual entries, return canUpdate / canDelete on them — absent means allowed. Setting all three to false gives a read-only library users still browse, preview and insert from, since insertion never touches your store. list cannot be disabled.

Nothing is fetched until the user opens the browser or the save dialoglist() is never called on editor load. The rail entry is present from the first paint whenever a provider is configured, so a slow or empty list() can neither delay the editor nor shift the sidebar; the browser shows skeleton rows on a first open, and reopens render the previous entries while refreshing underneath.

import {
  init,
  createLocalStorageSavedBlocksProvider,
} from "@templatical/editor";

// Zero-backend option, for demos and prototypes:
await init({
  container: "#editor",
  savedBlocks: createLocalStorageSavedBlocksProvider(),
});

// Or implement `SavedBlocksProvider` against your own API:
await init({ container: "#editor", savedBlocks: myProvider });

Off by default. With no savedBlocks provider the feature is entirely absent and none of its UI code is downloaded — the pick bar and both dialogs are lazily loaded chunks fetched only when actually used.

Ordering belongs to the provider: the browser renders list()'s order verbatim and never re-sorts, so you control it server-side. createdAt / updatedAt are display only — each entry shows a relative timestamp (hover for the absolute date) and both fields are optional.

New exports:

  • @templatical/typesSavedBlock, SavedBlocksListParams, SavedBlocksProvider
  • @templatical/coreuseSavedBlocks, createLocalStorageSavedBlocksProvider
  • @templatical/core/cloudcreateCloudSavedBlocksProvider
  • @templatical/editorsavedBlocks config option, plus re-exports of the provider factory and types
Breaking changes
  • useSavedModules is removed from @templatical/core/cloud. Use useSavedBlocks from @templatical/core with a provider — createCloudSavedBlocksProvider(authManager) for Cloud. The return shape changed: modules/loadModules/createModule/updateModule/deleteModulesavedBlocks/load/create/update/remove.
  • SavedModule is removed from @templatical/types. Use SavedBlock, whose createdAt/updatedAt are now optional (a browser-local or in-memory store may not track them).
  • initCloud()'s modules option is renamed to savedBlocks. modules: false becomes savedBlocks: false.
  • Editor translation keys renamed. blockActions.saveAsModuleblockActions.saveAsBlock, sidebarNav.browseModulessidebarNav.browseSavedBlocks, and the cloud chunk's modules.* namespace moved into the OSS chunk as savedBlocks.*. Only affects consumers overriding translations directly.

The Cloud REST contract is unchanged: ApiClient.listModules/createModule/updateModule/deleteModule and the saved-modules routes keep their names and paths.

Fixes
  • Cloud no longer renders a dead "save as block" button on plans without the saved-blocks entitlement. Availability is now a reactive signal on the capability, so the control appears only when the feature actually works.

All 9 @templatical/* packages are published at 0.21.0 — they share one version number.

Full changelog: https://docs.templatical.com/changelog