Extending

Plugins

Add fields to Xelqun Forms from your own package, with the same search, uploads, rows and saving as the built-in ones.

A plugin adds fields from its own repository. Built-in fields use the same contracts, so a plugin field can do what they do.

Installing a plugin

php artisan xelqun-forms:plugin acme/rating

That installs the npm package, adds the plugin to your Inertia entry file, and points Tailwind at its components.

Laying one out

A plugin is one repository, with a composer.json and a package.json.

{
    "name": "acme/rating",
    "autoload": { "psr-4": { "Acme\\Rating\\": "src/" } },
    "extra": {
        "laravel": { "providers": ["Acme\\Rating\\RatingServiceProvider"] },
        "xelqun": { "npm": "@acme/rating", "plugin": "ratingPlugin" }
    }
}

package.json ships your source, because the host's Vite compiles it. Declare the shared packages as peer dependencies, because a second copy of vue or reka-ui silently breaks reactivity and popovers.

{
    "name": "@acme/rating",
    "type": "module",
    "files": ["resources/js"],
    "exports": { ".": "./resources/js/index.ts" },
    "peerDependencies": {
        "@xelqun/forms": "^0.7.0",
        "reka-ui": "^2.11.0",
        "vue": "^3.5.0"
    }
}

Registering the renderer

import type { XelqunPlugin } from '@xelqun/forms';

export function ratingPlugin(): XelqunPlugin {
    return {
        id: 'acme/rating',
        components: {
            'acme/rating': () => import('./components/RatingField.vue'),
        },
    };
}

Plugin types need a vendor prefix, such as acme/rating. Names without one are reserved for built-in fields.

What a field can do

Implement a contract from Xelqun\Forms\Contracts, and the matching endpoint starts working for your field.

Contract What it gives you
HasSearchResults The search endpoint
AcceptsUploads The upload endpoint and storage on save
EmbedsUploads The same, for uploads kept inside a field's text
ContainsRows Rows with their own components
PersistsItself Saving somewhere other than a column
PersistsBeforeSave Doing something before the record is saved
NeedsServer A clear error on forms the server can't rebuild

Search only suggests values. The browser can post anything, so getTypeRules() has to check the value too.

To start building, see custom fields. The full guide lives in the package repository.