Skip to content

Commit

Permalink
Merge branch 'release/3.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
leandrocfe committed Aug 30, 2024
2 parents 244ba03 + de16ab4 commit 5a101d0
Show file tree
Hide file tree
Showing 11 changed files with 411 additions and 66 deletions.
127 changes: 116 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This package provides custom form fields for [Filament](https://filamentphp.com/

This package uses [LaravelLegends/pt-br-validator](https://github.com/LaravelLegends/pt-br-validator) to validate Brazilian Portuguese fields.

![image demo](https://raw.githubusercontent.com/leandrocfe/filament-ptbr-form-fields/develop/screenshots/v3-example.png)
![image demo](https://raw.githubusercontent.com/leandrocfe/filament-ptbr-form-fields/develop/screenshots/v3x-example.png)

## Installation

Expand Down Expand Up @@ -81,46 +81,151 @@ use Leandrocfe\FilamentPtbrFormFields\PhoneNumber;
PhoneNumber::make('phone_number')
```

If you want to use a custom phone number format, use the format() method with a string argument representing the desired format:
If you want to use a custom phone number format, use the `mask() method with a string argument representing the desired format:

```php
PhoneNumber::make('phone_number')
->format('99999-9999')
->mask('(99) 99999-9999')
```

```php
PhoneNumber::make('phone_number')
->format('(+99)(99)99999-9999')
->mask('+99 (99) 99999-9999')
```

### Money

To create a money input with the Brazilian currency symbol as the prefix, use:
To create a money input field, use the following syntax:

```php
use Leandrocfe\FilamentPtbrFormFields\Money;
Money::make('price')
->default('100,00')

#output: 100.00
```

This is suitable for use with `decimal` or `float` data types.

#### Using Integer Values

If you prefer to work with integer values, you can format the money input using the `intFormat()` method:

```php
use Leandrocfe\FilamentPtbrFormFields\Money;
Money::make('price')
->default(10000)
->intFormat()

#output: 10000
```
#### Getting the Raw State

To retrieve the raw state of the field, you can use the `dehydratedMask() method:

```php
use Leandrocfe\FilamentPtbrFormFields\Money;
Money::make('price')
->default('100,00')
->dehydrateMask()

If you want to remove the prefix, use the prefix() method with a null argument:
#output: 100,00
```

If you need to remove the prefix from the money input, simply pass null to the `prefix()` method:
```php
Money::make('price')
->prefix(null)
->prefix(null)
```
#### Currency Formatting

By default, the mask is removed from the input when it is submitted. If you want to keep the mask, use the dehydrateMask() method with a false argument:
This package leverages the `archtechx/money` package under the hood. By default, it uses the `BRL` (Brazilian Real) format for currency values.

If you want to switch to the `USD` (United States Dollar) format, you can do so with the following code:
```php
use Leandrocfe\FilamentPtbrFormFields\Currencies\USD;

Money::make('price')
->dehydrateMask(false)
->currency(USD::class)
->prefix('$')
```

The initial value of the input is '0,00'. If you want to change the initial value, use the initialValue() method with a string argument:
You can also define custom currencies to suit your specific needs:


```php

/*
* app/Currencies/EUR.php
*/

declare(strict_types=1);

namespace App\Currencies;

use ArchTech\Money\Currency;

class EUR extends Currency
{
/*
* Code of the currency.
*/
public string $code = 'EUR';

/*
* Name of the currency.
*/
public string $name = 'Euro';

/*
* Rate of this currency relative to the default currency.
*/
public float $rate = 1.0;

/*
* Number of decimals used in money calculations.
*/
public int $mathDecimals = 2;

/*
* Number of decimals used in the formatted value
*/
public int $displayDecimals = 2;

/*
* How many decimals of the currency's values should get rounded
*/
public int $rounding = 2;

/*
* Prefix placed at the beginning of the formatted value.
*/
public string $prefix = '€';

/*
* The language code.
*/
public string $locale = 'pt';

/*
* The character used to separate the decimal values.
*/
public string $decimalSeparator = '.';

/*
* The character used to separate groups of thousands
*/
public string $thousandsSeparator = ',';
}

```

```php
use App\Currencies\EUR;

Money::make('price')
->initialValue(null)
->currency(EUR::class)
->prefix('€')
```

### Address
Expand Down
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
}
],
"require": {
"php": "^8.1 || ^8.2",
"php": "^8.1 || ^8.2 || ^8.3",
"archtechx/money": "^0.5.1",
"filament/filament": "^3.0",
"illuminate/contracts": "^10.0 || ^11.0",
"laravellegends/pt-br-validator": "^10.0 || ^11.0",
"moneyphp/money": "^4.5",
"spatie/laravel-package-tools": "^1.14.0"
},
"require-dev": {
Expand Down
1 change: 0 additions & 1 deletion dist/mask.min.js

This file was deleted.

129 changes: 129 additions & 0 deletions resources/js/money.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/**
* All credit goes to
* https://mary-ui.com
* https://github.com/lagden/currency
*
* It works perfect with some tweaks.
*/
class Currency {
unmaskedValue = 0

constructor(input, opts = {}) {
this.opts = {
keyEvent: 'input',
triggerOnBlur: false,
init: false,
backspace: false,
maskOpts: {},
...opts,
}

if (input instanceof HTMLInputElement === false) {
throw new TypeError('The input should be a HTMLInputElement')
}

// Add fraction on initial value if missing
const parts = String(input.value).split('.')
input.value = parts.length === 1 ? `${parts.shift()}.00` : `${parts.shift()}.${parts.pop().padEnd(2, '0')}`

this.input = input
this.events = new Set()

// Initialize
if (this.opts.init) {
this.input.value = Currency.masking(this.input.value, this.opts.maskOpts)
}

// Listener
this.input.addEventListener(this.opts.keyEvent, this)
this.events.add(this.opts.keyEvent)

this.input.addEventListener('click', this)
this.events.add('click')

if (this.opts.triggerOnBlur) {
this.input.addEventListener('blur', this)
this.events.add('blur')
}
}

static getUnmasked() {
return this.unmaskedValue
}

static position(v) {
const nums = new Set(['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'])
const len = v.length

let cc = 0
for (let i = len - 1; i >= 0; i--) {
if (nums.has(v[i])) {
break
}
cc++
}

return String(v).length - cc
}

static masking(v, opts = {}) {
const {
empty = false,
locales = 'pt-BR',
options = {
minimumFractionDigits: 2,
},
} = opts

if (typeof v === 'number') {
v = v.toFixed(2)
}

const n = String(v).replace(/\D/g, '').replace(/^0+/g, '')
const t = n.padStart(3, '0')
const d = t.slice(-2)
const i = t.slice(0, t.length - 2)

if (empty && i === '0' && d === '00') {
return ''
}

this.unmaskedValue = `${i}.${d}`

return new Intl.NumberFormat(locales, options).format(this.unmaskedValue)
}

onMasking(event) {
if (this.opts.backspace && event?.inputType === 'deleteContentBackward') {
return
}

this.input.value = Currency.masking(this.input.value, this.opts.maskOpts)
const pos = Currency.position(this.input.value)
this.input.setSelectionRange(pos, pos)
}

onClick() {
const pos = Currency.position(this.input.value)
this.input.focus()
this.input.setSelectionRange(pos, pos)
}

destroy() {
for (const _event of this.events) {
this.input.removeEventListener(_event, this)
}
}

handleEvent(event) {
if (event.type === 'click') {
this.onClick(event)
} else {
this.onMasking(event)
}
}
}

if (!window.Currency) {
window.Currency = Currency
}
Binary file removed screenshots/v3-example.png
Binary file not shown.
Binary file added screenshots/v3x-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions src/Currencies/BRL.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Leandrocfe\FilamentPtbrFormFields\Currencies;

use ArchTech\Money\Currency;

class BRL extends Currency
{
public string $code = 'BRL';

public string $name = 'Real Brasileiro';

public float $rate = 1.0;

public int $mathDecimals = 2;

public int $displayDecimals = 2;

public int $rounding = 2;

public string $prefix = '';

public string $locale = 'pt-BR';

public string $decimalSeparator = ',';

public string $thousandsSeparator = '.';
}
30 changes: 30 additions & 0 deletions src/Currencies/USD.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Leandrocfe\FilamentPtbrFormFields\Currencies;

use ArchTech\Money\Currency;

class USD extends Currency
{
public string $code = 'USD';

public string $name = 'United States Dollar';

public float $rate = 1.0;

public int $mathDecimals = 2;

public int $displayDecimals = 2;

public int $rounding = 2;

public string $prefix = '';

public string $locale = 'en';

public string $decimalSeparator = '.';

public string $thousandsSeparator = ',';
}
4 changes: 1 addition & 3 deletions src/FilamentPtbrFormFields.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@

namespace Leandrocfe\FilamentPtbrFormFields;

class FilamentPtbrFormFields
{
}
class FilamentPtbrFormFields {}
Loading

0 comments on commit 5a101d0

Please sign in to comment.