Vue
@sealpixel/vue is a Vue 3 component around <sealpixel-editor>, with v-model:editLog for the log and the element's events as component events. Vue 3.4 and later.
Install
pnpm add @sealpixel/vuenpm install @sealpixel/vuevue 3.4 or later is a peer dependency. Optionally, app.use(Sealpixel) registers <SealpixelEditor> globally.
The starter
examples/starters/vue, a Vite app. Open it on StackBlitz. The component, quoted from the starter:
<script setup lang="ts">
import type { ExportResult } from '@sealpixel/core';
import { SealpixelEditor } from '@sealpixel/vue';
import { ref } from 'vue';
const editLog = ref<unknown>({
version: 1,
source: { id: 'landscape', width: 120, height: 80 },
plugins: { finetune: 1, filter: 1 },
ops: [
{ type: 'finetune.set', id: 'shared-1', params: { contrast: 0.2, saturation: 0.3 } },
{ type: 'filter.set', id: 'shared-2', preset: 'warm', strength: 0.6 },
],
});
const processed = ref('Press Download: the file name carries the SHA-256 of the result.');
function onProcess(r: ExportResult) {
processed.value = `exported ${r.width}x${r.height} sha256 ${r.hash}`;
}
</script>
<template>
<SealpixelEditor src="/landscape.png" theme="dark" v-model:editLog="editLog" @process="onProcess" />
<output data-testid="processed">{{ processed }}</output>
</template>v-model:editLog is controlled use: the ref holds { log, index } after the first change and the editor follows it. Without the model, pass defaultEditLog once and listen to @change when you want to save. @process gives the ExportResult of a Download.
Build setup
The Vue compiler has to know that sealpixel-* tags are custom elements, or it warns about unknown components wherever the raw tag appears in a template:
import vue from '@vitejs/plugin-vue';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
vue({
template: { compilerOptions: { isCustomElement: (tag) => tag.startsWith('sealpixel-') } },
}),
],
});That is all Vite needs. With another bundler, the worker URL and the .wasm asset have to survive, as the overview says.
Server-side rendering
The component runs in the browser only. In Nuxt, wrap it in <ClientOnly> and add the isCustomElement rule to vue.compilerOptions in nuxt.config; the same rule as in the Vite config above. Rendering the tag on the server is harmless, but object props such as editLog only reach the element on the client.
Headless
useSealpixel returns a session and its state as a shallow ref, disposed with the component scope:
/** Headless composable: a session whose state is a shallow ref, disposed with the scope. */
export function useSealpixel(options: SessionOptions): {
session: EditorSession;
state: ShallowRef<SessionState>;
} {
const session = createEditorSession(options);
const state = shallowRef(session.getState());
const unsubscribe = session.subscribe((s) => {
state.value = s;
});
onScopeDispose(() => {
unsubscribe();
session.dispose();
});
return { session, state };
}Server rendering
Above the client limit the browser cannot export, see Working copy. Render the original on your server with @sealpixel/render: it takes the original and the edit log from getEditLog(). See Render on your server and the Node starter. The renderer does not depend on Vue. In Nuxt it runs in a server route under server/api/.
TypeScript
import type { EditLogState, SessionState } from '@sealpixel/vue';
import type { ExportResult, SealpixelError, SourceDescriptor } from '@sealpixel/core';The component's emits are typed: update:editLog and change with EditLogState, process with ExportResult, error with SealpixelError, load with SourceDescriptor. The exposed element and the methods getSession, getEditLog, undo, redo, export and download are reachable through a template ref, and typed on the component instance:
const editor = useTemplateRef<InstanceType<typeof SealpixelEditor>>('editor');
const saved = editor.value?.getEditLog();With show-export="auto", the default, the Export button appears only when you listen to @process.