Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .fvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"flutter": "stable",
"flavors": {}
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ migrate_working_dir/
.dart_tool/
.packages
build/

# FVM Version Cache
.fvm/
28 changes: 28 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "example",
"cwd": "example",
"request": "launch",
"type": "dart"
},
{
"name": "example (profile mode)",
"cwd": "example",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "example (release mode)",
"cwd": "example",
"request": "launch",
"type": "dart",
"flutterMode": "release"
}
]
}
8 changes: 8 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"[dart]": {
"editor.formatOnSave": false,
"editor.rulers": [80],
},
"dart.lineLength": 80,
"dart.flutterSdkPath": ".fvm/versions/stable"
}
39 changes: 35 additions & 4 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class MyHomePage extends StatefulWidget {
class _MyHomePageState extends State<MyHomePage> {
TextEditingController controller = TextEditingController();
String? data;
GlobalKey<InternationalPhoneNumberInputState> inputKey = GlobalKey();
CountryCodeModel countryCodeModel = CountryCodeModel(name: "United States", dial_code: "+1", code: "US");


@override
void initState() {
Expand All @@ -55,13 +58,33 @@ class _MyHomePageState extends State<MyHomePage> {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
GestureDetector(
onTap: () {
inputKey.currentState?.showFlagBottomSheet();
},
child: Container(
alignment: AlignmentDirectional.centerStart,
padding: const EdgeInsetsDirectional.symmetric(vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FlagView(
countryCodeModel: countryCodeModel,
size: 32,
isFlat: false),
const SizedBox(width: 5),
Text(countryCodeModel.name),
],
),
),
),
InternationalPhoneNumberInput(
key: inputKey,
height: 60,
controller: controller,
inputFormatters: const [],
formatter: MaskedInputFormatter('### ### ## ##'),
initCountry: CountryCodeModel(
name: "United States", dial_code: "+1", code: "US"),
initCountry: countryCodeModel,
betweenPadding: 23,
onInputChanged: (phone) {
print(phone.code);
Expand All @@ -70,6 +93,13 @@ class _MyHomePageState extends State<MyHomePage> {
print(phone.rawFullNumber);
print(phone.rawNumber);
print(phone.rawDialCode);
setState(() {
countryCodeModel = CountryCodeModel(
name: phone.name,
dial_code: phone.dial_code,
code: phone.code,
);
});
},
loadFromJson: loadFromJson,
dialogConfig: DialogConfig(
Expand Down Expand Up @@ -112,7 +142,8 @@ class _MyHomePageState extends State<MyHomePage> {
borderRadius: BorderRadius.circular(8),
),
flatFlag: true,
noFlag: false,
noFlag: true,
flex: 5,
textStyle: const TextStyle(
color: Colors.black,
fontSize: 16,
Expand Down Expand Up @@ -162,6 +193,6 @@ class _MyHomePageState extends State<MyHomePage> {
}

Future<String> loadFromJson() async {
return await rootBundle.loadString('assets/countries/country_list.json');
return await rootBundle.loadString('assets/countries/country_list_en.json');
}
}
101 changes: 54 additions & 47 deletions lib/intl_phone_number_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import 'view/flag_view.dart';
import 'view/rixa_textfield.dart';

export 'package:flutter_multi_formatter/formatters/masked_input_formatter.dart';
export 'package:intl_phone_number_field/view/flag_view.dart';

export 'models/country_code_model.dart';
export 'models/country_config.dart';
Expand Down Expand Up @@ -64,10 +65,10 @@ class InternationalPhoneNumberInput extends StatefulWidget {

@override
State<InternationalPhoneNumberInput> createState() =>
_InternationalPhoneNumberInputState();
InternationalPhoneNumberInputState();
}

class _InternationalPhoneNumberInputState
class InternationalPhoneNumberInputState
extends State<InternationalPhoneNumberInput> {
List<CountryCodeModel>? countries;
late CountryCodeModel selected;
Expand Down Expand Up @@ -121,6 +122,43 @@ class _InternationalPhoneNumberInputState
}
}

void showFlagBottomSheet() {
if (!widget.inactive && countries != null) {
showModalBottomSheet(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(30)),
),
barrierColor: Colors.black.withOpacity(0.6),
isScrollControlled: true,
backgroundColor: widget.dialogConfig.backgroundColor,
context: context,
builder: (context) {
return SingleChildScrollView(
child: CountryCodeBottomSheet(
countries: countries!,
selected: selected,
onSelected: (countryCodeModel) {
setState(() {
selected = countryCodeModel;
});
if (widget.onInputChanged != null) {
widget.onInputChanged!(
IntPhoneNumber(
name: selected.name,
code: selected.code,
dial_code: selected.dial_code,
number: widget.controller.text.trimLeft().trimRight(),
),
);
}
},
dialogConfig: widget.dialogConfig,
),
);
});
}
}

@override
Widget build(BuildContext context) {
return Column(
Expand All @@ -129,45 +167,11 @@ class _InternationalPhoneNumberInputState
height: widget.height,
child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
Expanded(
flex: 10,
flex: widget.countryConfig.flex,
child: SizedBox(
height: widget.height,
child: TextButton(
onPressed: () {
if (!widget.inactive && countries != null) {
showModalBottomSheet(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(30))),
barrierColor: Colors.black.withOpacity(0.6),
isScrollControlled: true,
backgroundColor:
widget.dialogConfig.backgroundColor,
context: context,
builder: (context) {
return SingleChildScrollView(
child: CountryCodeBottomSheet(
countries: countries!,
selected: selected,
onSelected: (countryCodeModel) {
setState(() {
selected = countryCodeModel;
});
if (widget.onInputChanged != null) {
widget.onInputChanged!(IntPhoneNumber(
code: selected.code,
dial_code: selected.dial_code,
number: widget.controller.text
.trimLeft()
.trimRight()));
}
},
dialogConfig: widget.dialogConfig,
),
);
});
}
},
onPressed: showFlagBottomSheet,
style: TextButton.styleFrom(
minimumSize: Size.zero,
padding: EdgeInsets.zero,
Expand All @@ -180,12 +184,14 @@ class _InternationalPhoneNumberInputState
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FlagView(
countryCodeModel: selected,
isFlat: widget.countryConfig.flatFlag,
size: widget.countryConfig.flagSize,
),
const SizedBox(width: 8),
if (!widget.countryConfig.noFlag) ...[
FlagView(
countryCodeModel: selected,
isFlat: widget.countryConfig.flatFlag,
size: widget.countryConfig.flagSize,
),
const SizedBox(width: 8),
],
Text(
selected.dial_code,
style: widget.countryConfig.textStyle,
Expand All @@ -197,7 +203,7 @@ class _InternationalPhoneNumberInputState
)),
SizedBox(width: widget.betweenPadding),
Expanded(
flex: 18,
flex: widget.phoneConfig.flex,
child: RixaTextField(
hintText: widget.phoneConfig.hintText ?? "",
hintStyle: widget.phoneConfig.hintStyle,
Expand Down Expand Up @@ -231,6 +237,7 @@ class _InternationalPhoneNumberInputState
onChanged: (text) {
if (widget.onInputChanged != null) {
widget.onInputChanged!(IntPhoneNumber(
name: selected.name,
code: selected.code,
dial_code: selected.dial_code,
number: text.trimLeft().trimRight()));
Expand Down Expand Up @@ -292,9 +299,9 @@ class _InternationalPhoneNumberInputState
}

class IntPhoneNumber {
String code, dial_code, number;
String code, dial_code, number, name;
IntPhoneNumber(
{required this.code, required this.dial_code, required this.number});
{required this.code, required this.dial_code, required this.number, this.name = ""});
String get fullNumber => "$dial_code $number";
String get rawNumber => number.replaceAll(" ", "");
String get rawDialCode => dial_code.replaceAll("+", "");
Expand Down
2 changes: 2 additions & 0 deletions lib/models/country_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ class CountryConfig {
Decoration decoration;
bool flatFlag;
double flagSize;
final int flex;
CountryConfig({
this.noFlag = false,
this.flagSize = 30,
this.flex = 10,
this.flatFlag = false,
Decoration? decoration,
this.textStyle = const TextStyle(
Expand Down
2 changes: 2 additions & 0 deletions lib/models/phone_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ class PhoneConfig {
AutovalidateMode autovalidateMode;
final TextStyle? floatingLabelStyle;
final TextInputAction textInputAction;
final int flex;
PhoneConfig(
{this.focusedColor = const Color(0xFF6D59BD),
this.enabledColor = const Color(0xFF6D59BD),
this.errorPadding = const EdgeInsets.only(top: 14),
this.radius = 8,
this.flex = 18,
this.autovalidateMode = AutovalidateMode.onUserInteraction,
this.textInputAction = TextInputAction.done,
this.hintText = "Phone Number",
Expand Down