Skip to content

kirbyuse ​

kirbyuse adds the Kirby-specific layer on top of Vue: types for window.panel, composables for common Panel tasks and prop sets for fields and blocks.

Versions

kirbyuse 2 pairs with kirbyup 4 and Kirby 6. Kirby 4 and 5 plugins use kirbyuse 1 with kirbyup 3.

Installation ​

bash
pnpm add -D kirbyuse
bash
npm install -D kirbyuse
bash
yarn add -D kirbyuse

Imports ​

Kirby 6 exposes vue through an import map, and kirbyup leaves vue out of the bundle. The Composition API comes from vue, everything Kirby-specific from kirbyuse:

js
import { computed, ref, usePanel } from 'kirbyuse'
import { usePanel } from 'kirbyuse'
import { computed, ref } from 'vue'

At runtime, vue resolves to the Panel's own copy. Your plugin and the Panel share one Vue.

Panel Types ​

usePanel returns window.panel with types for every service:

js
import { usePanel } from 'kirbyuse'

const panel = usePanel()

panel.notification.success('Saved')
panel.dialog.open({ /* ... */ })
panel.view.reload()

To type the global directly, import the package once in the entry file:

js
// src/index.js
import 'kirbyuse'

window.panel.notification.success('Types work')
//           ^? (property) notification: PanelNotification

No TypeScript required, the hints work in JavaScript files as well.

Composables ​

useContent ​

Reactive access to the content of the current view:

js
import { useContent } from 'kirbyuse'
import { watch } from 'vue'

const { currentContent, contentChanges, hasChanges, update } = useContent()

watch(hasChanges, (changed) => {
  if (changed)
    console.log('Unsaved changes')
})

update({ title: 'New title' })

currentContent reflects the editor state including unsaved changes, contentChanges holds only the diff and update writes into it.

useDialog ​

Opens Kirby's dialogs and resolves with the result:

js
import { useDialog } from 'kirbyuse'

const { openTextDialog, openFieldsDialog } = useDialog()

const confirmed = await openTextDialog('Delete this entry?')

const result = await openFieldsDialog({
  fields: {
    email: { type: 'email', label: 'Email' },
  },
})
// result: { email: '...' } or undefined when cancelled

openFieldsDialog takes an onSubmit handler to validate before the dialog closes. Return false to keep it open.

useI18n ​

Translates the objects Kirby uses for labels:

js
import { useI18n } from 'kirbyuse'

const { t } = useI18n()

t({ en: 'Hello', de: 'Hallo' }) // Follows the Panel language

For Kirby's own translation strings, panel.t() is the right call.

All Composables ​

ComposableReturns
usePanelThe typed window.panel
useApipanel.api for requests to the backend
useApppanel.app, the Vue application instance
useContent{ content, currentContent, contentChanges, hasChanges, isEditable, update }
useDialog{ openTextDialog, openFieldsDialog }
useBlock{ field, open, update } for custom block components
useI18n{ t }
useHelpersKirby's $helper utilities
useLibraryKirby's $library bundle, such as dayjs

Prop Sets ​

kirbyuse/props exports the props Kirby passes to a component, so you spread them instead of copying them:

js
import { field } from 'kirbyuse/props'

defineProps({ ...field })

The individual field props such as label, disabled and required are available as well.

Plugin Assets ​

For assets that should load on demand, register them once and resolve them by file name:

HelperPurpose
registerPluginAssets(assets)Registers { filename, url } pairs, usually from a PHP-side asset list
resolvePluginAsset(filename)Returns the registered asset
loadPluginModule(filename)Imports a registered JavaScript module, cached

Resources ​