Composables
Connect Vue controls to PPTX editor state and commands with composables.
Call editor-state composables during setup() inside PptxEditorRoot. The packaged <PptxEditor> provides that root for its default slot. Each composable exports a named return type, Use<Name>Return.
usePptxSource and useFonts prepare input for the root. Call them in the parent component's setup() when needed.
Connect a command button
This button runs a toolbar command and shows why the command cannot run:
<script setup lang="ts">
import { computed } from 'vue';
import { useEditorCommand, useTranslation } from '@pptx-editor.dev/vue';
import { translateKeyOrText } from '@pptx-editor.dev/core/editor';
const bold = useEditorCommand('text.bold');
const { t } = useTranslation();
const title = computed(() => {
const reason = bold.disabledReason.value;
return reason ? translateKeyOrText(t, reason) : t('toolbar.bold');
});
</script>
<template>
<button
type="button"
:aria-disabled="!bold.isEnabled.value || undefined"
:aria-pressed="bold.isActive.value"
:aria-label="t('toolbar.bold')"
:title="title"
@mousedown.prevent
@click="bold.execute()"
>
B
</button>
</template>useEditorCommand(slot: MaybeRefOrGetter<ChromeSlotId>): UseEditorCommandReturn takes a slot identifier from the toolbar slot reference, or a ref or getter that returns one. The state follows the slot.
| Member | Type | Description |
|---|---|---|
execute(value?) | boolean | Runs the slot's command, with a value for value slots. Returns true when the engine ran it, and false on a refusal. |
isEnabled | ComputedRef<boolean> | Whether the command can run now. |
isActive | ComputedRef<boolean> | Whether a toggle control shows as pressed. |
disabledReason | ComputedRef<string | null> | A translation key, or the engine's own text, when the command cannot run. |
value | ComputedRef<string | number | undefined> | The value a value slot shows, such as a font size or a family. |
The types in these signatures, such as ChromeSlotId, CommandResult, EditorSnapshot, and PptxEditorInstance, are exported from @pptx-editor.dev/vue. You do not need an import from @pptx-editor.dev/core to type your handlers.
Read state
useEditorState returns a read-only shallow ref for one slice of the snapshot. The ref changes only when that slice changes:
<script setup lang="ts">
import { useEditorState } from '@pptx-editor.dev/vue';
const current = useEditorState((s) => s.currentSlide);
const total = useEditorState((s) => s.slides.length);
</script>
<template>
<span>{{ current + 1 }} / {{ total }}</span>
</template>Pass a comparator for an object slice. Common fields include status, slides, currentSlide, selection, format, mode, canUndo, canRedo, presentationView, lastRejection, and lastRemoval.
Templates unwrap only top-level refs:
| Value | In a template | In script |
|---|---|---|
Top-level or destructured ref, such as current | current | current.value |
| Ref inside a returned object | bold.isEnabled.value | bold.isEnabled.value |
| Composable | Return type | Shape |
|---|---|---|
useEditorState(selector, isEqual?) | UseEditorStateReturn<T> | Readonly<ShallowRef<T>>. isEqual defaults to Object.is. |
usePptxEditor() | UsePptxEditorReturn | Readonly<ShallowRef<PptxEditorInstance | null>>. null before the editor mounts and outside a root. |
useEditorColorMode() | UseEditorColorModeReturn | { colorMode: ComputedRef<ResolvedColorMode> }: 'light' or 'dark', after 'system' resolves. |
useTranslation() | UseTranslationReturn | { t: Translate }. t follows the root's locale. See Language. |
usePptxEditor
Use the instance for actions and one-time reads:
<script setup lang="ts">
import { usePptxEditor } from '@pptx-editor.dev/vue';
const props = defineProps<{ upload: (bytes: Uint8Array) => Promise<void> }>();
const editor = usePptxEditor();
function save() {
const saved = editor.value?.save();
if (saved) void props.upload(saved);
}
</script>
<template>
<button :disabled="!editor" @click="save">Save</button>
</template>A direct snapshot() call does not create a Vue subscription. Use useEditorState for values that you render.
Choose a composable
State members are refs. Function members are plain functions.
Formatting
| Composable | Return type | Members |
|---|---|---|
useFontFormat() | UseFontFormatReturn | format: UseEditorStateReturn<FontFormatRead | null>. isEnabled: ComputedRef<boolean>. apply(update: FontFormatCommand): writes the fields as one undo step and returns whether the engine accepted them. |
useParagraphFormat() | UseParagraphFormatReturn | format: UseEditorStateReturn<ParagraphFormatRead | null>. isEnabled. apply(update: ParagraphFormatCommand): one undo step. |
useBulletFormat() | UseBulletFormatReturn | format: UseEditorStateReturn<BulletFormatRead | null | undefined>; null is no list, and undefined means the paragraphs differ. isEnabled. apply(format: BulletFormat | null): null turns the list off. |
useEditorValueCommand(slot) | UseEditorValueCommandReturn<V, S> | A typed value slot. See Apply a value. |
Slides and panes
| Composable | Return type | Members |
|---|---|---|
useSlideLayouts() | UseSlideLayoutsReturn | UseEditorStateReturn<readonly SlideLayoutSummary[]>: the deck's slide layouts, in gallery order. |
useNotesPane() | UseNotesPaneReturn | open: ComputedRef<boolean>. setOpen(open) and toggle(). |
useSlideshow() | UseSlideshowReturn | controller: Readonly<ShallowRef<SlideshowController | null>>. start('start' | 'current') and stop(). |
Dialogs, menus, and notices
| Composable | Return type | Members |
|---|---|---|
useEditorDialog(key) | UseEditorDialogReturn | isOpen and isAvailable: ComputedRef<boolean>. open(returnFocusTo?) and close(). key is a PptxEditorDialogKey. See Open a dialog from your control. |
usePageSetupDialog(), useParagraphDialog(), useFontDialog(), useBulletsAndNumberingDialog(), useColumnsDialog(), useImageAltTextDialog(), useImagePropertiesDialog() | UsePageSetupDialogReturn, UseParagraphDialogReturn, and so on: each is UseDialogReturn<Fields> | The draft of an open dialog. values, errors, and isEnabled are refs. setValue(name, value), apply(), and cancel(). Call them inside the dialog. See Dialog parts and draft state. |
useBackgroundDialog() | UseBackgroundDialogReturn | UseDialogReturn<BackgroundDialogFields> with reset(). |
useContextMenuRequest() | UseContextMenuRequestReturn | ContextMenuRequest | null: the open canvas context menu. Each request mounts the menu anew, so the value is fixed for the menu's life. |
useContextMenuTarget() | UseContextMenuTargetReturn | HTMLElement | null: the element the open context menu opened on. |
useOpenFailure({ t? }) | UseOpenFailureReturn | failure, message, and kept: computed refs. dismiss(failure?). t translates message. See Show a banner or a toast. |
useHyperlinkPopup(), useHyperlinkPopupInstance(active?) | UseHyperlinkPopupReturn, UseHyperlinkPopupInstanceReturn | state: a computed ref to the link popup's state. The actions of the React hook. |
Fonts
| Composable | Return type | Members |
|---|---|---|
useFonts(source, ...fragments) or useFonts(...origins) | UseFontsReturn | A MarkedFontResolver with a stable identity, for the fonts prop. Each argument can be a ref or a getter. See Fonts. |
useFontFamily() | UseFontFamilyReturn | value, theme, options, groups, isEnabled, and disabledReason: computed refs. isCurrent(row) and setValue(family). Use it for your own font picker. See Build the list from useFontFamily. |
usePptxSource(source, options?) | UsePptxSourceReturn | document, fonts, error, and isLoading: computed refs. source and options can be refs or getters. See the font loading and download rules in Open a presentation. |
Build your own chrome
Call these composables in setup to connect your controls to the editor.
Zoom
useZoom(): UseZoomReturn reads and sets the slide zoom:
<script setup lang="ts">
import { useZoom } from '@pptx-editor.dev/vue';
const { zoom, isFit, fit, zoomIn, zoomOut, canZoomIn, canZoomOut } = useZoom();
</script>
<template>
<div role="group" aria-label="Zoom">
<button :disabled="!canZoomOut" aria-label="Zoom out" @click="zoomOut">-</button>
<span>{{ Math.round(zoom * 100) }}%</span>
<button :disabled="!canZoomIn" aria-label="Zoom in" @click="zoomIn">+</button>
<button :aria-pressed="isFit" @click="fit">Fit</button>
</div>
</template>zoom, isFit, canZoomIn, and canZoomOut are computed refs. setZoom(zoom), fit(), reset(), zoomIn(), and zoomOut() are functions, and levels is an array. The members are the same as in the React hook.
Events
useEditorEvent(event, handler): void calls handler each time the event occurs, until the component unmounts:
import { useEditorEvent } from '@pptx-editor.dev/vue';
useEditorEvent('rejection', (rejection) => console.info(rejection.reason));The events are change, selectionChange, rejection, and openFailure, as in the React hook.
Other composables
| Composable | Return type | Members |
|---|---|---|
useEditorSnapshot(editor) | Readonly<Ref<number>> | A counter that changes on each editor change. editor can be a ref or a getter. Prefer useEditorState. |
useScopeClassName() | UseScopeClassNameReturn | ComputedRef<'' | 'pptx-editor ' | 'pptx-editor dark '>: the scope classes for the root element of your own part. See Style your controls. |
useEditorHostDocument() | UseEditorHostDocumentReturn | Readonly<ShallowRef<Document | null>>: the document that the slide is mounted in. |
Find, caret, and undo steps
| Composable | Return type | Members |
|---|---|---|
useDocumentSearch() | UseDocumentSearchReturn | The find session as computed refs (query, matchCase, wholeWord, matches, activeIndex, activeMatch), and the actions of the React hook. |
useEditorCaret() | UseEditorCaretReturn | Readonly<Ref<EditorCaret | null>>: the caret while text is edited. |
useHistoryGroup({ kind }) | UseHistoryGroupReturn | ref, a function ref for the control, and options() for each command of the gesture. |
<script setup lang="ts">
import { useEditorValueCommand, useHistoryGroup } from '@pptx-editor.dev/vue';
const group = useHistoryGroup({ kind: 'range' });
const size = useEditorValueCommand('font.size');
</script>
<template>
<input
type="range"
aria-label="Font size"
:ref="group.ref"
@input="size.execute(Number(($event.target as HTMLInputElement).value), group.options())"
/>
</template>Labels
| Composable | Return type | Members |
|---|---|---|
useChromeTranslate(overrides?) | UseChromeTranslateReturn | The t of the nearest compound, else the root's locale. |
useToolbarContext() | UseToolbarContextReturn | { t }: a ref to the host's t on the nearest compound. |
useToolbarLabel(), useToolbarLabelFor(t) | UseToolbarLabelReturn, UseToolbarLabelForReturn | (key) => string, as in React. |
PptxEditorToolbar, PptxEditorMenu, PptxEditorContextMenu, PptxEditorSlideRail, PptxEditorStatusBar, PptxEditorFindBar, PptxEditorOpenFailure, PptxEditorFontNotice, and PptxEditorEditNotice take the t prop.
Apply a value
useEditorValueCommand reads the value of a value slot and applies a new one, with the slot's type from ToolbarValueMap. This slider sets the font size:
<script setup lang="ts">
import { ref } from 'vue';
import { useEditorValueCommand } from '@pptx-editor.dev/vue';
const size = useEditorValueCommand('font.size');
const error = ref<string | null>(null);
function apply(event: Event) {
const result = size.execute(Number((event.target as HTMLInputElement).value));
error.value = result.ok ? null : result.reason;
}
</script>
<template>
<label :title="size.disabledReason.value ?? undefined">
{{ size.value.value === null ? 'Mixed' : `${size.value.value} pt` }}
<input
type="range"
min="8"
max="96"
:value="size.value.value ?? 18"
:disabled="!size.isEnabled.value"
@input="apply"
/>
<output aria-live="polite">{{ error }}</output>
</label>
</template>font.size takes points, or { step: 1 } and { step: -1 } for one step of the size list. null means mixed or unavailable.
| Member | Type | Description |
|---|---|---|
execute(value, options?) | CommandResult | Runs the command. A refusal gives ok: false and the reason, such as disabled.invalidValue. |
value | ComputedRef<S | null> | The value the slot shows, or null when mixed or unavailable. |
options | ComputedRef<readonly V[]> | The slot's fixed choices. A slot with a free value has none. |
isEnabled, disabledReason | ComputedRef<boolean>, ComputedRef<string | null> | As useEditorCommand gives them. |
The two composables return different results from execute: useEditorCommand returns a boolean, because a toolbar button only needs to know if the command ran, and useEditorValueCommand returns the CommandResult, because a value control shows why the engine refused a value.
To make the values of one slider drag one undo step, pass { historyGroup } from editor.value.beginHistoryGroup(). See Group a slider or a stepper.
Limits
- Call composables during
setup()insidePptxEditorRoot. Outside it,usePptxEditor().valueisnull. canUndoreports undo availability, not unsaved changes. Track saves yourself.- Dialog draft composables read a draft. They do not open the dialog; use
useEditorDialog(key)for that. disabledReasoncan be a translation key. Show it withtranslateKeyOrText(t, reason)from@pptx-editor.dev/core/editor.