diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index c8efc85..513dfde 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"smart_auth","path":"/Users/tornike/.pub-cache/hosted/pub.dev/smart_auth-2.0.0/","native_build":true,"dependencies":[]}],"android":[{"name":"smart_auth","path":"/Users/tornike/.pub-cache/hosted/pub.dev/smart_auth-2.0.0/","native_build":true,"dependencies":[]}],"macos":[{"name":"smart_auth","path":"/Users/tornike/.pub-cache/hosted/pub.dev/smart_auth-2.0.0/","native_build":true,"dependencies":[]}],"linux":[{"name":"smart_auth","path":"/Users/tornike/.pub-cache/hosted/pub.dev/smart_auth-2.0.0/","native_build":true,"dependencies":[]}],"windows":[{"name":"smart_auth","path":"/Users/tornike/.pub-cache/hosted/pub.dev/smart_auth-2.0.0/","native_build":true,"dependencies":[]}],"web":[{"name":"smart_auth","path":"/Users/tornike/.pub-cache/hosted/pub.dev/smart_auth-2.0.0/","dependencies":[]}]},"dependencyGraph":[{"name":"smart_auth","dependencies":[]}],"date_created":"2024-02-10 07:31:36.266830","version":"3.16.9"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"smart_auth","path":"/Users/tornike/.pub-cache/hosted/pub.dev/smart_auth-2.0.0/","native_build":true,"dependencies":[]}],"android":[{"name":"smart_auth","path":"/Users/tornike/.pub-cache/hosted/pub.dev/smart_auth-2.0.0/","native_build":true,"dependencies":[]}],"macos":[{"name":"smart_auth","path":"/Users/tornike/.pub-cache/hosted/pub.dev/smart_auth-2.0.0/","native_build":true,"dependencies":[]}],"linux":[{"name":"smart_auth","path":"/Users/tornike/.pub-cache/hosted/pub.dev/smart_auth-2.0.0/","native_build":true,"dependencies":[]}],"windows":[{"name":"smart_auth","path":"/Users/tornike/.pub-cache/hosted/pub.dev/smart_auth-2.0.0/","native_build":true,"dependencies":[]}],"web":[{"name":"smart_auth","path":"/Users/tornike/.pub-cache/hosted/pub.dev/smart_auth-2.0.0/","dependencies":[]}]},"dependencyGraph":[{"name":"smart_auth","dependencies":[]}],"date_created":"2024-02-10 07:31:36.266830","version":"3.16.9"} diff --git a/example/lib/demo/pinput_templates/only_bottom_cursor.dart b/example/lib/demo/pinput_templates/only_bottom_cursor.dart index 4e2b89b..f279a0f 100644 --- a/example/lib/demo/pinput_templates/only_bottom_cursor.dart +++ b/example/lib/demo/pinput_templates/only_bottom_cursor.dart @@ -73,6 +73,27 @@ class _OnlyBottomCursorState extends State { showCursor: true, cursor: cursor, preFilledWidget: preFilledWidget, + pinItemBuilder: (item, theme) { + return Stack( + children: [ + Align( + alignment: Alignment.center, + child: Text(item, style: theme.textStyle), + ), + Align( + alignment: Alignment.bottomCenter, + child: Container( + width: 56, + height: 3, + decoration: BoxDecoration( + color: Colors.grey, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ], + ); + }, ); } } diff --git a/lib/src/pinput.dart b/lib/src/pinput.dart index 3a70b51..c7991a8 100644 --- a/lib/src/pinput.dart +++ b/lib/src/pinput.dart @@ -64,6 +64,7 @@ class Pinput extends StatefulWidget { this.focusNode, this.preFilledWidget, this.separatorBuilder, + this.pinItemBuilder, this.smsCodeMatcher = PinputConstants.defaultSmsCodeMatcher, this.senderPhoneNumber, this.androidSmsAutofillMethod = AndroidSmsAutofillMethod.none, @@ -204,10 +205,14 @@ class Pinput extends StatefulWidget { /// Widget that is displayed before field submitted. final Widget? preFilledWidget; - /// Builds a Pinput separator + /// Builds a [Pinput] separator /// If null SizedBox(width: 8) will be used final JustIndexedWidgetBuilder? separatorBuilder; + /// Builds a [Pinput] item + /// If null the default _PinItem will be used + final PinItemWidgetBuilder? pinItemBuilder; + /// Defines how [Pinput] fields are being placed inside [Row] final MainAxisAlignment mainAxisAlignment; @@ -506,6 +511,13 @@ class Pinput extends StatefulWidget { defaultValue: PinputConstants._defaultSeparator, ), ); + properties.add( + DiagnosticsProperty( + 'pinItemBuilder', + pinItemBuilder, + defaultValue: null, + ), + ); properties.add( DiagnosticsProperty( 'obscuringWidget', diff --git a/lib/src/pinput_state.dart b/lib/src/pinput_state.dart index 94b849b..606159a 100644 --- a/lib/src/pinput_state.dart +++ b/lib/src/pinput_state.dart @@ -481,7 +481,7 @@ class _PinputState extends State separatorBuilder: widget.separatorBuilder, mainAxisAlignment: widget.mainAxisAlignment, children: Iterable.generate(widget.length).map((index) { - return _PinItem(state: this, index: index); + return _PinItem(state: this, index: index, builder: widget.pinItemBuilder); }).toList(), ); } diff --git a/lib/src/widgets/_pin_item.dart b/lib/src/widgets/_pin_item.dart index 1a3e161..bb73892 100644 --- a/lib/src/widgets/_pin_item.dart +++ b/lib/src/widgets/_pin_item.dart @@ -1,10 +1,17 @@ part of '../pinput.dart'; +typedef PinItemWidgetBuilder = Widget Function(String, PinTheme); + class _PinItem extends StatelessWidget { final _PinputState state; final int index; + final PinItemWidgetBuilder? builder; - const _PinItem({required this.state, required this.index}); + const _PinItem({ + required this.state, + required this.index, + required this.builder, + }); @override Widget build(BuildContext context) { @@ -73,11 +80,12 @@ class _PinItem extends StatelessWidget { return SizedBox(key: key, child: state.widget.obscuringWidget); } - return Text( - state.widget.obscureText ? state.widget.obscuringCharacter : pin[index], - key: key, - style: pinTheme.textStyle, - ); + final content = state.widget.obscureText + ? state.widget.obscuringCharacter + : pin[index]; + return (builder != null) + ? SizedBox(key: key, child: builder!(content, pinTheme)) + : Text(content, key: key, style: pinTheme.textStyle); } final isActiveField = index == pin.length;