diff --git a/CHANGELOG.md b/CHANGELOG.md index a4d1e29..3ad68f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.12.0 +- Novos formatters: `CESTInputFormatter()` e `NCMInputFormatter()`, por [juliogyn](https://github.com/juliogyn). + ## 1.11.0 - Novo formatter: `IOFInputFormatter()`. diff --git a/README.md b/README.md index 429767d..904e705 100644 --- a/README.md +++ b/README.md @@ -132,3 +132,11 @@ Para inicializar um `TextEditingController` com o texto já formatado, basta esc final dataController = TextEditingController(text: UtilData.obterDataDDMMAAAA(DateTime(2020, 12, 31))); final cnpjController = TextEditingController(text: UtilBrasilFields.obterCnpj('11222333444455')); ``` + +--- + + + + + +Made with [contrib.rocks](https://contrib.rocks). \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart index 71c72d8..c3fc395 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -114,6 +114,14 @@ class MyApp extends StatelessWidget { label: 'IOF', formatter: IOFInputFormatter(), ), + RowFormatters( + label: 'NCM', + formatter: NCMInputFormatter(), + ), + RowFormatters( + label: 'CEST', + formatter: CESTInputFormatter(), + ), ], ), const Text('Em breve'), diff --git a/example/macos/Runner.xcodeproj/project.pbxproj b/example/macos/Runner.xcodeproj/project.pbxproj index c84862c..d9333e4 100644 --- a/example/macos/Runner.xcodeproj/project.pbxproj +++ b/example/macos/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ @@ -235,6 +235,7 @@ /* Begin PBXShellScriptBuildPhase section */ 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -344,7 +345,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -423,7 +424,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -470,7 +471,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/example/pubspec.lock b/example/pubspec.lock index 053a077..7fa6c1c 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -23,7 +23,7 @@ packages: path: ".." relative: true source: path - version: "1.11.0" + version: "1.12.0" characters: dependency: transitive description: diff --git a/lib/brasil_fields.dart b/lib/brasil_fields.dart index 2be476c..59f30db 100644 --- a/lib/brasil_fields.dart +++ b/lib/brasil_fields.dart @@ -4,6 +4,7 @@ export 'src/formatters/altura_input_formatter.dart'; export 'src/formatters/cartao_bancario_input_formatter.dart'; export 'src/formatters/centavos_input_formatter.dart'; export 'src/formatters/cep_input_formatter.dart'; +export 'src/formatters/cest_input_formatter.dart'; export 'src/formatters/cnpj_input_formatter.dart'; export 'src/formatters/compound_formatters/cpf_ou_cpnj_formatter.dart'; export 'src/formatters/cpf_input_formatter.dart'; @@ -11,6 +12,7 @@ export 'src/formatters/data_input_formatter.dart'; export 'src/formatters/hora_input_formatter.dart'; export 'src/formatters/iof_input_formatter.dart'; export 'src/formatters/km_input_formatter.dart'; +export 'src/formatters/ncm_input_formatter.dart'; export 'src/formatters/peso_input_formatter.dart'; export 'src/formatters/placa_veiculo_formatter.dart'; export 'src/formatters/real_input_formatter.dart'; diff --git a/lib/src/formatters/cest_input_formatter.dart b/lib/src/formatters/cest_input_formatter.dart new file mode 100644 index 0000000..171264f --- /dev/null +++ b/lib/src/formatters/cest_input_formatter.dart @@ -0,0 +1,42 @@ +import 'package:brasil_fields/src/interfaces/compoundable_formatter.dart'; +import 'package:flutter/services.dart'; + +/// Formata o valor do campo com a máscara CEST `XX.XXX.XX`. +class CESTInputFormatter extends TextInputFormatter + implements CompoundableFormatter { + // Define o tamanho máximo do campo. + @override + int get maxLength => 7; + + @override + TextEditingValue formatEditUpdate( + TextEditingValue oldValue, TextEditingValue newValue) { + final newValueLength = newValue.text.length; + + if (newValueLength > maxLength) { + return oldValue; + } + + var selectionIndex = newValue.selection.end; + var substrIndex = 0; + final newText = StringBuffer(); + + if (newValueLength >= 3) { + newText.write('${newValue.text.substring(0, substrIndex = 2)}.'); + if (newValue.selection.end >= 2) selectionIndex++; + } + if (newValueLength >= 6) { + newText.write('${newValue.text.substring(2, substrIndex = 5)}.'); + if (newValue.selection.end >= 5) selectionIndex++; + } + + if (newValueLength >= substrIndex) { + newText.write(newValue.text.substring(substrIndex)); + } + + return TextEditingValue( + text: newText.toString(), + selection: TextSelection.collapsed(offset: selectionIndex), + ); + } +} diff --git a/lib/src/formatters/iof_input_formatter.dart b/lib/src/formatters/iof_input_formatter.dart index 728132c..1826607 100644 --- a/lib/src/formatters/iof_input_formatter.dart +++ b/lib/src/formatters/iof_input_formatter.dart @@ -1,7 +1,6 @@ import 'package:flutter/services.dart'; -/// Formata o valor do campo com a máscara `9,99999`. - +/// Formata o valor do campo com a máscara `9,99999` class IOFInputFormatter extends TextInputFormatter { @override TextEditingValue formatEditUpdate( diff --git a/lib/src/formatters/ncm_input_formatter.dart b/lib/src/formatters/ncm_input_formatter.dart new file mode 100644 index 0000000..c62c9a3 --- /dev/null +++ b/lib/src/formatters/ncm_input_formatter.dart @@ -0,0 +1,41 @@ +import 'package:brasil_fields/src/interfaces/compoundable_formatter.dart'; +import 'package:flutter/services.dart'; + +/// Formata o valor do campo com a máscara de NCM: `XXXX.XX.XX` +class NCMInputFormatter extends TextInputFormatter + implements CompoundableFormatter { + @override + int get maxLength => 8; + + @override + TextEditingValue formatEditUpdate( + TextEditingValue oldValue, TextEditingValue newValue) { + final newValueLength = newValue.text.length; + + if (newValueLength > maxLength) { + return oldValue; + } + + var selectionIndex = newValue.selection.end; + var substrIndex = 0; + final newText = StringBuffer(); + + if (newValueLength >= 5) { + newText.write('${newValue.text.substring(0, substrIndex = 4)}.'); + if (newValue.selection.end >= 4) selectionIndex++; + } + if (newValueLength >= 7) { + newText.write('${newValue.text.substring(4, substrIndex = 6)}.'); + if (newValue.selection.end >= 6) selectionIndex++; + } + + if (newValueLength >= substrIndex) { + newText.write(newValue.text.substring(substrIndex)); + } + + return TextEditingValue( + text: newText.toString(), + selection: TextSelection.collapsed(offset: selectionIndex), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 55a912d..0fe58b8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: brasil_fields description: O jeito mais fácil de utilizar padrões e formatos brasileiros em seu projeto Dart. -version: 1.11.0 +version: 1.12.0 homepage: https://github.com/flutterbootcamp/brasil_fields repository: https://github.com/flutterbootcamp/brasil_fields issue_tracker: https://github.com/flutterbootcamp/brasil_fields/issues diff --git a/test/brasil_fields_test.dart b/test/brasil_fields_test.dart index 04708bc..dd80b7a 100644 --- a/test/brasil_fields_test.dart +++ b/test/brasil_fields_test.dart @@ -342,4 +342,20 @@ void main() { await tester.enterText(find.byType(TextField), '12345678'); expect(textController.text, '1,234567'); }); + + testWidgets('NCMInputFormatter', (WidgetTester tester) async { + final textController = TextEditingController(); + + await tester.pumpWidget(boilerplate(NCMInputFormatter(), textController)); + await tester.enterText(find.byType(TextField), '03099000'); + expect(textController.text, '0309.90.00'); + }); + + testWidgets('CESTInputFormatter', (WidgetTester tester) async { + final textController = TextEditingController(); + + await tester.pumpWidget(boilerplate(CESTInputFormatter(), textController)); + await tester.enterText(find.byType(TextField), '0101800'); + expect(textController.text, '01.018.00'); + }); }