PHPackages                             imperazim/libform - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. imperazim/libform

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

imperazim/libform
=================

Form library for PocketMine plugins

v1.0.0(11mo ago)00MITPHPPHP ^8.2

Since Jun 3Pushed 11mo agoCompare

[ Source](https://github.com/ImperaZim/LibForm)[ Packagist](https://packagist.org/packages/imperazim/libform)[ RSS](/packages/imperazim-libform/feed)WikiDiscussions stable Synced 1mo ago

READMEChangelog (1)Dependencies (1)Versions (3)Used By (0)

LibForm
=======

[](#libform)

**Form Library for PocketMine (Minecraft PE)**

Overview
--------

[](#overview)

**LibForm** is a PHP library that simplifies the creation of Minecraft forms in PocketMine. It offers two approaches:

1. **Class-based**
    Extend abstract classes to define form structure, elements, and behavior. Passing `true` as the third constructor argument automatically sends the form to the player.
2. **Dynamic (Fluent Interface)**
    Build forms on-the-fly using method chaining. Ideal for quick, concise form creation without defining separate classes.

Supported form types:

- **List Form (LongForm)**
- **Modal Form**
- **Custom Form**

---

Installation
------------

[](#installation)

Add LibForm to your project with Composer:

```
composer require imperazim/libform
```

Then include classes under the `imperazim\form` namespace.

---

Form Types
----------

[](#form-types)

### 1. List Form (LongForm)

[](#1-list-form-longform)

A scrollable list of buttons, optionally with custom textures or icons.

#### 1.1. Class-based

[](#11-class-based)

1. **Extend `LongForm`**
2. **Override** three methods:

    - `title()`: returns a `Title` object.
    - `content()`: returns a `Content` object.
    - `buttons()`: returns a `ButtonCollection`. Each `Button` can have a texture and a callback via `ButtonResponse`.
3. **Instantiate** with `true` to automatically send to the player.

```
use imperazim\form\long\LongForm;
use imperazim\form\long\elements\Button;
use imperazim\form\long\elements\ButtonTexture;
use imperazim\form\long\elements\ButtonCollection;
use imperazim\form\long\response\ButtonResponse;
use imperazim\form\base\Title;
use imperazim\form\base\Content;

class MyListForm extends LongForm {
    protected function title(Player $player, FormData $formData): Title {
        return new Title('Main Menu');
    }

    protected function content(Player $player, FormData $formData): Content {
        return new Content('Select an option:');
    }

    protected function buttons(Player $player, FormData $formData): ButtonCollection {
        return ButtonCollection::fromArray([
            new Button(
                'Option 1',
                new ButtonTexture('textures/ui/icon_recipe', ButtonTexture::PATH),
                new ButtonResponse(function(Player $player): FormResult {
                    $player->sendMessage("You clicked Option 1!");
                    return FormResult::CLOSE;
                })
            ),
            new Button(
                'Option 2',
                null,
                new ButtonResponse(function(Player $player): FormResult {
                    $player->sendMessage("Option 2 selected.");
                    return FormResult::CLOSE;
                })
            ),
        ]);
    }
}

// Instantiation sends the form immediately:
new MyListForm($player, $formData, true);
```

#### 1.2. Dynamic (Fluent Interface)

[](#12-dynamic-fluent-interface)

1. **Call** `DynamicLongForm::create($title)`.
2. **Chain** methods:

    - `setContent($text)`
    - `addButton($text, $texturePathOrNull, $callback)`
    - `sendTo($player)`

```
use imperazim\form\long\DynamicLongForm;

DynamicLongForm::create("Quick Menu")
    ->setContent("What do you want to do?")
    ->addButton(
        "Status",
        'textures/blocks/diamond_block',
        function(Player $player): FormResult {
            $player->sendMessage("Status chosen!");
            return FormResult::CLOSE;
        }
    )
    ->addButton(
        "Settings",
        null,
        function(Player $player): FormResult {
            $player->sendMessage("Opening settings...");
            return FormResult::CLOSE;
        }
    )
    ->sendTo($player);
```

---

### 2. Modal Form

[](#2-modal-form)

A two-button confirmation dialog (confirm/cancel).

#### 2.1. Class-based

[](#21-class-based)

1. **Extend** `ModalForm`.
2. **Override** four methods:

    - `title()`: returns a `Title`.
    - `content()`: returns a `Content`.
    - `button1()`: typically `ModalButton::confirm($text)`.
    - `button2()`: typically `ModalButton::cancel($text)`.
3. **Implement** `onConfirm()` to handle the “confirm” action. Optionally override `onCancel()` for custom “cancel” behavior.
4. **Instantiate** with `true` to send immediately.

```
use imperazim\form\modal\ModalForm;
use imperazim\form\modal\elements\ModalButton;
use imperazim\form\base\Title;
use imperazim\form\base\Content;

class ConfirmationForm extends ModalForm {
    protected function title(Player $player, FormData $formData): Title {
        return new Title('Confirmation');
    }

    protected function content(Player $player, FormData $formData): Content {
        return new Content('Are you sure you want to delete this item?');
    }

    protected function button1(Player $player, FormData $formData): ModalButton {
        return ModalButton::confirm('Yes');
    }

    protected function button2(Player $player, FormData $formData): ModalButton {
        return ModalButton::cancel('No');
    }

    protected function onConfirm(Player $player, FormData $formData): FormResult {
        $player->sendMessage('Item deleted!');
        return FormResult::CLOSE;
    }

    // Optionally:
    // protected function onCancel(Player $player, FormData $formData): FormResult { ... }
}

// Sends the form automatically:
new ConfirmationForm($player, $formData, true);
```

#### 2.2. Dynamic (Fluent Interface)

[](#22-dynamic-fluent-interface)

1. **Call** `DynamicModalForm::create($title)`.
2. **Chain** methods:

    - `setContent($text)`
    - `setButton1($text, $callback)`
    - `setButton2($text, $callback)`
    - `sendTo($player)`

```
use imperazim\form\modal\DynamicModalForm;

DynamicModalForm::create("Save Changes")
    ->setContent("Do you want to save your changes?")
    ->setButton1("Save", function(Player $player, ModalResponse $response): FormResult {
        $player->sendMessage('Changes saved!');
        return FormResult::CLOSE;
    })
    ->setButton2("Cancel", function(Player $player, ModalResponse $response): FormResult {
        $player->sendMessage('Operation canceled.');
        return FormResult::CLOSE;
    })
    ->sendTo($player);
```

---

### 3. Custom Form

[](#3-custom-form)

A flexible form with multiple input elements (text fields, toggles, sliders, dropdowns, etc.).

#### 3.1. Class-based

[](#31-class-based)

1. **Extend** `CustomForm`.
2. **Override** two methods:

    - `title()`: returns a `Title`.
    - `elements()`: returns an `ElementCollection` built from individual element objects (`Label`, `Input`, `Toggle`, `Slider`, `Dropdown`, `StepSlider`).
3. **Implement** `onSubmit()` to process submitted values via `CustomResponse`.
4. **Instantiate** with `true` to send immediately.

```
use imperazim\form\custom\CustomForm;
use imperazim\form\custom\elements\ElementCollection;
use imperazim\form\custom\elements\Input;
use imperazim\form\custom\elements\Toggle;
use imperazim\form\custom\elements\Slider;
use imperazim\form\custom\elements\Dropdown;
use imperazim\form\custom\elements\Option;
use imperazim\form\custom\response\CustomResponse;
use imperazim\form\base\Title;

class SettingsForm extends CustomForm {
    protected function title(Player $player, FormData $formData): Title {
        return new Title('General Settings');
    }

    protected function elements(Player $player, FormData $formData): ElementCollection {
        return ElementCollection::fromArray([
            new Input('username', 'Username:', 'Type your name', $player->getName()),
            new Toggle('notifications', 'Enable notifications?', true),
            new Slider('volume', 'Sound Volume', 0, 100, 1, 50),
            new Dropdown('language', 'Language', [
                new Option('en', 'English'),
                new Option('es', 'Spanish'),
                new Option('pt', 'Portuguese')
            ], 'en')
        ]);
    }

    protected function onSubmit(Player $player, CustomResponse $response): FormResult {
        $username = $response->getInput('username');
        $volume = $response->getSlider('volume');
        $languageId = $response->getSelectedOption('language')->getId();

        $player->sendMessage("Settings saved: $username, Volume $volume, Language $languageId");
        return FormResult::CLOSE;
    }
}

// Sends the form automatically:
new SettingsForm($player, $formData, true);
```

#### 3.2. Dynamic (Fluent Interface)

[](#32-dynamic-fluent-interface)

1. **Call** `DynamicCustomForm::create($title)`.
2. **Chain** methods:

    - `addElement($elementObject)` for each element.
    - `setOnSubmit($callback)` to handle submission.
    - `sendTo($player)` to display.

```
use imperazim\form\custom\DynamicCustomForm;
use imperazim\form\custom\elements\Input;
use imperazim\form\custom\elements\Toggle;

DynamicCustomForm::create("Player Profile")
    ->addElement(new Input('nickname', 'Nickname:', 'Enter your nickname...', $player->getName()))
    ->addElement(new Toggle('pvp', 'Enable PvP?', false))
    ->setOnSubmit(function(Player $player, CustomResponse $response): FormResult {
        $nick = $response->getInput('nickname');
        $pvpStatus = $response->getToggle('pvp') ? 'enabled' : 'disabled';
        $player->sendMessage("Nickname: $nick | PvP: $pvpStatus");
        return FormResult::CLOSE;
    })
    ->sendTo($player);
```

---

CustomForm Elements
-------------------

[](#customform-elements)

ElementDescriptionExample Creation**Label**Informational, non-interactive text`new Label('Welcome!')`**Input**Text input field`new Input('id', 'Label', 'Placeholder', 'Default value')`**Toggle**On/off switch`new Toggle('id', 'Enable feature?', true)`**Slider**Numeric range selector`new Slider('id', 'Volume', 0, 100, 5, 50)`**Dropdown**Single-select option list`new Dropdown('id', 'Choose a color', [new Option('r','Red')], 'r')`**StepSlider**Visual step selector`new StepSlider('id', 'Difficulty', [new Option('easy','Easy')], 'easy')`---

State Management (FormData)
---------------------------

[](#state-management-formdata)

Use `FormData` to share data between forms:

```
use imperazim\form\FormData;

// Create FormData with initial values:
$formData = new FormData([
    'playerName' => $player->getName(),
    'score'      => 1000,
]); // Instantiate FormData and optional, the parameter accepts arrays!

// Retrieve values in any form:
$playerName = $formData->get('playerName'); // string
$score      = $formData->get('score');      // int
or
$playerName = $formData['playerName']; // string
$score      = $formData['score'];      // int
```

---

Flow Control (FormResult)
-------------------------

[](#flow-control-formresult)

After a form interaction, return one of:

- **FormResult::CLOSE** — close the form for the player.
- **FormResult::KEEP** — keep the form open (e.g., for validation, re-prompt).

```
protected function onSubmit(Player $player, CustomResponse $response): FormResult {
    // If "name" is empty, show an error and keep the form open:
    if ($response->getInput('name') === '') {
        $player->sendMessage("The 'name' field cannot be empty!");
        return FormResult::KEEP;
    }

    // Otherwise, close the form:
    return FormResult::CLOSE;
}
```

---

Example: Test Command
---------------------

[](#example-test-command)

This example registers a `/testform` command to open different types of forms:

```
namespace your\plugin\namespace;

use pocketmine\plugin\PluginBase;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\player\Player;
use imperazim\form\FormData;
use imperazim\form\long\DynamicLongForm;
use imperazim\form\modal\DynamicModalForm;
use imperazim\form\custom\DynamicCustomForm;

class Main extends PluginBase {
    public function onEnable(): void {
        $this->getServer()->getCommandMap()->register('testform', new FormCommand());
    }
}

class FormCommand extends Command {
    public function __construct() {
        parent::__construct("testform", "Test command for forms", "/testform ");
    }

    public function execute(CommandSender $sender, string $label, array $args): void {
        if (!$sender instanceof Player) {
            $sender->sendMessage("This command can only be used by a player.");
            return;
        }

        $type = $args[0] ?? '';
        switch (strtolower($type)) {
            case 'long':
                // Class-based ListForm (auto-sent)
                new MyListForm($sender, new FormData(), true);
                break;

            case 'long_dynamic':
                // Dynamic ListForm
                DynamicLongForm::create("Quick Menu")
                    ->setContent("Choose:")
                    ->addButton("Option A", null, fn(Player $p) => FormResult::CLOSE)
                    ->sendTo($sender);
                break;

            case 'custom':
                // Class-based CustomForm (auto-sent)
                new SettingsForm($sender, new FormData(), true);
                break;

            case 'modal_dynamic':
                // Dynamic ModalForm
                DynamicModalForm::create("Confirmation")
                    ->setContent("Do you wish to continue?")
                    ->setButton1("Yes", fn(Player $p, $r) => FormResult::CLOSE)
                    ->setButton2("No", fn(Player $p, $r) => FormResult::CLOSE)
                    ->sendTo($sender);
                break;

            default:
                $sender->sendMessage("Usage: /testform ");
        }
    }
}
```

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance50

Moderate activity, may be stable

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

349d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/0b9fc308a46bb613e71af2a06deea6798019ee6cdff0c77a20ba399d904310bc?d=identicon)[ImperaZim](/maintainers/ImperaZim)

---

Top Contributors

[![ImperaZim](https://avatars.githubusercontent.com/u/92953608?v=4)](https://github.com/ImperaZim "ImperaZim (7 commits)")

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/imperazim-libform/health.svg)

```
[![Health](https://phpackages.com/badges/imperazim-libform/health.svg)](https://phpackages.com/packages/imperazim-libform)
```

###  Alternatives

[antoineaugusti/easyphpcharts

A PHP class for chartjs.org charts.

252.8k](/packages/antoineaugusti-easyphpcharts)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
