Custom MoneyInput form field

I am using 'akaunting/laravel-money' package and custom cast that helps to store the value in cents in database and return money object while reading. ( A common approach for money)

The only issue was with filament TextInput which doesn't understands the object so I had to make a custom field.

This is the code:

<?php

namespace App\Forms\Components;

use Filament\Forms\Components\TextInput;
use Filament\Support\RawJs;

class MoneyInput extends TextInput
{
    use Concerns\HasMoneyAttributes;

    protected function setUp(): void
    {
        parent::setUp();

        $this->inputMode('decimal')
            ->minValue(0)
            ->prefix(fn (MoneyInput $component) => $component->getCurrency()->getPrefix())
            ->suffix(fn (MoneyInput $component) => $component->getCurrency()->getSuffix())
            ->stripCharacters(fn (MoneyInput $component) => $component->getCurrency()->getDecimalMark())
            ->formatStateUsing(function (MoneyInput $component, $state) {
                if (is_array($state) && array_key_exists('amount', $state)) {
                    return money($state['amount'], key($state['currency']))->valueWithoutZeroes();
                }

                return $state;
            })
            ->dehydrateStateUsing(function (MoneyInput $component, $state) {
                return str_replace($component->getCurrency()->getThousandsSeparator(), '', $state);
            });
    }

    public function getMask(): string|RawJs|null
    {
        if (! $this->evaluate($this->moneyMask)) {
            return null;
        }

        return RawJs::make(sprintf(
            "\$money(\$input, '%s', '%s', %d);",
            $this->getCurrency()->getDecimalMark(),
            $this->getCurrency()->getThousandsSeparator(),
            $this->getCurrency()->getPrecision()
        ));
    }
}

and in the form:
MoneyInput::make('price')->required(),


Now it is working but I wanted to know if there is scope for improvement.
Was this page helpful?