Skip to content

Commit 5a101d0

Browse files
committed
Merge branch 'release/3.1.0'
2 parents 244ba03 + de16ab4 commit 5a101d0

11 files changed

+411
-66
lines changed

README.md

+116-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This package provides custom form fields for [Filament](https://filamentphp.com/
44

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

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

99
## Installation
1010

@@ -81,46 +81,151 @@ use Leandrocfe\FilamentPtbrFormFields\PhoneNumber;
8181
PhoneNumber::make('phone_number')
8282
```
8383

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

8686
```php
8787
PhoneNumber::make('phone_number')
88-
->format('99999-9999')
88+
->mask('(99) 99999-9999')
8989
```
9090

9191
```php
9292
PhoneNumber::make('phone_number')
93-
->format('(+99)(99)99999-9999')
93+
->mask('+99 (99) 99999-9999')
9494
```
9595

9696
### Money
9797

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

100100
```php
101101
use Leandrocfe\FilamentPtbrFormFields\Money;
102102
Money::make('price')
103+
->default('100,00')
104+
105+
#output: 100.00
106+
```
107+
108+
This is suitable for use with `decimal` or `float` data types.
109+
110+
#### Using Integer Values
111+
112+
If you prefer to work with integer values, you can format the money input using the `intFormat()` method:
113+
114+
```php
115+
use Leandrocfe\FilamentPtbrFormFields\Money;
116+
Money::make('price')
117+
->default(10000)
118+
->intFormat()
119+
120+
#output: 10000
103121
```
122+
#### Getting the Raw State
123+
124+
To retrieve the raw state of the field, you can use the `dehydratedMask() method:
125+
126+
```php
127+
use Leandrocfe\FilamentPtbrFormFields\Money;
128+
Money::make('price')
129+
->default('100,00')
130+
->dehydrateMask()
104131

105-
If you want to remove the prefix, use the prefix() method with a null argument:
132+
#output: 100,00
133+
```
106134

135+
If you need to remove the prefix from the money input, simply pass null to the `prefix()` method:
107136
```php
108137
Money::make('price')
109-
->prefix(null)
138+
->prefix(null)
110139
```
140+
#### Currency Formatting
111141

112-
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:
142+
This package leverages the `archtechx/money` package under the hood. By default, it uses the `BRL` (Brazilian Real) format for currency values.
113143

144+
If you want to switch to the `USD` (United States Dollar) format, you can do so with the following code:
114145
```php
146+
use Leandrocfe\FilamentPtbrFormFields\Currencies\USD;
147+
115148
Money::make('price')
116-
->dehydrateMask(false)
149+
->currency(USD::class)
150+
->prefix('$')
117151
```
118152

119-
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:
153+
You can also define custom currencies to suit your specific needs:
154+
120155

121156
```php
157+
158+
/*
159+
* app/Currencies/EUR.php
160+
*/
161+
162+
declare(strict_types=1);
163+
164+
namespace App\Currencies;
165+
166+
use ArchTech\Money\Currency;
167+
168+
class EUR extends Currency
169+
{
170+
/*
171+
* Code of the currency.
172+
*/
173+
public string $code = 'EUR';
174+
175+
/*
176+
* Name of the currency.
177+
*/
178+
public string $name = 'Euro';
179+
180+
/*
181+
* Rate of this currency relative to the default currency.
182+
*/
183+
public float $rate = 1.0;
184+
185+
/*
186+
* Number of decimals used in money calculations.
187+
*/
188+
public int $mathDecimals = 2;
189+
190+
/*
191+
* Number of decimals used in the formatted value
192+
*/
193+
public int $displayDecimals = 2;
194+
195+
/*
196+
* How many decimals of the currency's values should get rounded
197+
*/
198+
public int $rounding = 2;
199+
200+
/*
201+
* Prefix placed at the beginning of the formatted value.
202+
*/
203+
public string $prefix = '€';
204+
205+
/*
206+
* The language code.
207+
*/
208+
public string $locale = 'pt';
209+
210+
/*
211+
* The character used to separate the decimal values.
212+
*/
213+
public string $decimalSeparator = '.';
214+
215+
/*
216+
* The character used to separate groups of thousands
217+
*/
218+
public string $thousandsSeparator = ',';
219+
}
220+
221+
```
222+
223+
```php
224+
use App\Currencies\EUR;
225+
122226
Money::make('price')
123-
->initialValue(null)
227+
->currency(EUR::class)
228+
->prefix('€')
124229
```
125230

126231
### Address

composer.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616
}
1717
],
1818
"require": {
19-
"php": "^8.1 || ^8.2",
19+
"php": "^8.1 || ^8.2 || ^8.3",
20+
"archtechx/money": "^0.5.1",
2021
"filament/filament": "^3.0",
2122
"illuminate/contracts": "^10.0 || ^11.0",
2223
"laravellegends/pt-br-validator": "^10.0 || ^11.0",
24+
"moneyphp/money": "^4.5",
2325
"spatie/laravel-package-tools": "^1.14.0"
2426
},
2527
"require-dev": {

dist/mask.min.js

-1
This file was deleted.

resources/js/money.js

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/**
2+
* All credit goes to
3+
* https://mary-ui.com
4+
* https://github.com/lagden/currency
5+
*
6+
* It works perfect with some tweaks.
7+
*/
8+
class Currency {
9+
unmaskedValue = 0
10+
11+
constructor(input, opts = {}) {
12+
this.opts = {
13+
keyEvent: 'input',
14+
triggerOnBlur: false,
15+
init: false,
16+
backspace: false,
17+
maskOpts: {},
18+
...opts,
19+
}
20+
21+
if (input instanceof HTMLInputElement === false) {
22+
throw new TypeError('The input should be a HTMLInputElement')
23+
}
24+
25+
// Add fraction on initial value if missing
26+
const parts = String(input.value).split('.')
27+
input.value = parts.length === 1 ? `${parts.shift()}.00` : `${parts.shift()}.${parts.pop().padEnd(2, '0')}`
28+
29+
this.input = input
30+
this.events = new Set()
31+
32+
// Initialize
33+
if (this.opts.init) {
34+
this.input.value = Currency.masking(this.input.value, this.opts.maskOpts)
35+
}
36+
37+
// Listener
38+
this.input.addEventListener(this.opts.keyEvent, this)
39+
this.events.add(this.opts.keyEvent)
40+
41+
this.input.addEventListener('click', this)
42+
this.events.add('click')
43+
44+
if (this.opts.triggerOnBlur) {
45+
this.input.addEventListener('blur', this)
46+
this.events.add('blur')
47+
}
48+
}
49+
50+
static getUnmasked() {
51+
return this.unmaskedValue
52+
}
53+
54+
static position(v) {
55+
const nums = new Set(['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'])
56+
const len = v.length
57+
58+
let cc = 0
59+
for (let i = len - 1; i >= 0; i--) {
60+
if (nums.has(v[i])) {
61+
break
62+
}
63+
cc++
64+
}
65+
66+
return String(v).length - cc
67+
}
68+
69+
static masking(v, opts = {}) {
70+
const {
71+
empty = false,
72+
locales = 'pt-BR',
73+
options = {
74+
minimumFractionDigits: 2,
75+
},
76+
} = opts
77+
78+
if (typeof v === 'number') {
79+
v = v.toFixed(2)
80+
}
81+
82+
const n = String(v).replace(/\D/g, '').replace(/^0+/g, '')
83+
const t = n.padStart(3, '0')
84+
const d = t.slice(-2)
85+
const i = t.slice(0, t.length - 2)
86+
87+
if (empty && i === '0' && d === '00') {
88+
return ''
89+
}
90+
91+
this.unmaskedValue = `${i}.${d}`
92+
93+
return new Intl.NumberFormat(locales, options).format(this.unmaskedValue)
94+
}
95+
96+
onMasking(event) {
97+
if (this.opts.backspace && event?.inputType === 'deleteContentBackward') {
98+
return
99+
}
100+
101+
this.input.value = Currency.masking(this.input.value, this.opts.maskOpts)
102+
const pos = Currency.position(this.input.value)
103+
this.input.setSelectionRange(pos, pos)
104+
}
105+
106+
onClick() {
107+
const pos = Currency.position(this.input.value)
108+
this.input.focus()
109+
this.input.setSelectionRange(pos, pos)
110+
}
111+
112+
destroy() {
113+
for (const _event of this.events) {
114+
this.input.removeEventListener(_event, this)
115+
}
116+
}
117+
118+
handleEvent(event) {
119+
if (event.type === 'click') {
120+
this.onClick(event)
121+
} else {
122+
this.onMasking(event)
123+
}
124+
}
125+
}
126+
127+
if (!window.Currency) {
128+
window.Currency = Currency
129+
}

screenshots/v3-example.png

-232 KB
Binary file not shown.

screenshots/v3x-example.png

505 KB
Loading

src/Currencies/BRL.php

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Leandrocfe\FilamentPtbrFormFields\Currencies;
6+
7+
use ArchTech\Money\Currency;
8+
9+
class BRL extends Currency
10+
{
11+
public string $code = 'BRL';
12+
13+
public string $name = 'Real Brasileiro';
14+
15+
public float $rate = 1.0;
16+
17+
public int $mathDecimals = 2;
18+
19+
public int $displayDecimals = 2;
20+
21+
public int $rounding = 2;
22+
23+
public string $prefix = '';
24+
25+
public string $locale = 'pt-BR';
26+
27+
public string $decimalSeparator = ',';
28+
29+
public string $thousandsSeparator = '.';
30+
}

src/Currencies/USD.php

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Leandrocfe\FilamentPtbrFormFields\Currencies;
6+
7+
use ArchTech\Money\Currency;
8+
9+
class USD extends Currency
10+
{
11+
public string $code = 'USD';
12+
13+
public string $name = 'United States Dollar';
14+
15+
public float $rate = 1.0;
16+
17+
public int $mathDecimals = 2;
18+
19+
public int $displayDecimals = 2;
20+
21+
public int $rounding = 2;
22+
23+
public string $prefix = '';
24+
25+
public string $locale = 'en';
26+
27+
public string $decimalSeparator = '.';
28+
29+
public string $thousandsSeparator = ',';
30+
}

src/FilamentPtbrFormFields.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,4 @@
22

33
namespace Leandrocfe\FilamentPtbrFormFields;
44

5-
class FilamentPtbrFormFields
6-
{
7-
}
5+
class FilamentPtbrFormFields {}

0 commit comments

Comments
 (0)