Skip to content

Commit

Permalink
feat(deriv_ui): [MOBC-750] add deriv_numpad to deriv_ui (#434)
Browse files Browse the repository at this point in the history
* feat: add numpad to deriv_ui

* chore: minor refactor

* chore: add enable/disable of numpad button
  • Loading branch information
behnam-deriv authored Feb 14, 2024
1 parent cecda78 commit 3802e2e
Show file tree
Hide file tree
Showing 39 changed files with 2,881 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/deriv_ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Here is the detailed structure of the components included in this package:
- [Banner](./lib/components/banner/README.md)
- [Date Range Picker](./lib/components/date_range_picker/README.md)
- [Expandable bottom sheet](./lib/components/expandable_bottom_sheet/README.md)
- [Numpad](./lib/components/numpad/README.md)
- [Form Builder](./lib/components/form_builder/README.md)
- [Grouped List View](./lib/components/grouped_list_view/README.md)

Expand Down
10 changes: 10 additions & 0 deletions packages/deriv_ui/assets/icons/ic_currency_swap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/deriv_ui/assets/icons/ic_handle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
183 changes: 183 additions & 0 deletions packages/deriv_ui/example/lib/numpad/main.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import 'dart:async';

import 'package:deriv_ui/deriv_ui.dart';
import 'package:deriv_theme/deriv_theme.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Homepage(),
);
}
}

class Homepage extends StatelessWidget {
const Homepage({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('DerivNumberPad Example'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
final controller =
StreamController<ExchangeRateModel>.broadcast();

final Timer timer =
Timer.periodic(const Duration(seconds: 5), (Timer timer) {
controller.add(
ExchangeRateModel(
baseCurrency: 'BTC',
targetCurrency: 'USD',
exchangeRate: (23 * timer.tick).toDouble(),
),
);
});

showModalBottomSheet<void>(
isScrollControlled: true,
context: context,
backgroundColor: Colors.transparent,
builder: (BuildContext context) => Column(
mainAxisSize: MainAxisSize.min,
children: [
NumberPad.withCurrencyExchanger(
onClose: (type, closeType, result) {},
title: 'Amount',
exchangeRatesStream: controller.stream,
initialExchangeRate: ExchangeRateModel(
baseCurrency: 'BTC',
targetCurrency: 'USD',
exchangeRate: 42800,
),
primaryCurrency: CurrencyDetail(0.123, 'BTC'),
label: NumberPadLabel(
onValidate: (value) {
if (value.isEmpty) {
return NumpadValidationText(
enableActionButton: false,
text: RichText(
text: TextSpan(
text: 'Please enter an amount',
style: context.theme.textStyle(
textStyle: TextStyles.captionBold,
color: context.theme.colors.blue,
),
),
),
);
}
if (double.parse(value) > 50) {
return NumpadValidationText(
enableActionButton: false,
text: RichText(
textAlign: TextAlign.center,
text: TextSpan(
text:
'You have reached the daily transfer limit of [50,000.00] USD between your USD Wallet and Deriv X.',
style: context.theme.textStyle(
textStyle: TextStyles.captionBold,
color: context.theme.colors.blue,
),
),
),
);
} else {
return NumpadValidationText(
text: RichText(
text: TextSpan(
children: [
TextSpan(
text: 'This looks good! Hehe',
style: context.theme.textStyle(
textStyle: TextStyles.captionBold,
color: context.theme.colors.disabled,
),
),
],
),
),
);
}
},
actionOK: 'OK',
),
),
],
),
);
},
child: const Text('Numpad with currency exchange'),
),
ElevatedButton(
onPressed: () {
showModalBottomSheet<void>(
isScrollControlled: true,
context: context,
backgroundColor: Colors.transparent,
builder: (BuildContext context) => Column(
mainAxisSize: MainAxisSize.min,
children: [
NumberPad(
numberPadType: NumberPadWidgetType.singleInput,
currency: 'USD',
firstInputTitle: 'Amount',
formatter: NumberFormat.decimalPattern(),
firstInputInitialValue: 20,
firstInputMaximumValue: 100,
firstInputMinimumValue: 10,
label: NumberPadLabel(
semanticNumberPadBottomSheetHandle:
'semanticNumberPadBottomSheetHandle',
warnValueCantBeLessThan: (Object input, Object minValue,
Object currency) =>
'$input can\'t be less than $minValue $currency',
warnValueCantBeGreaterThan: (Object input,
Object maxValue, Object currency) =>
'$input can\'t be greater than $maxValue $currency',
warnDoubleInputValueCantBeLessThan: (Object input,
Object minValue, Object currency) =>
'Invalid $input. $input can\'t be less than $minValue $currency',
warnDoubleInputValueCantBeGreaterThan: (Object input,
Object maxValue, Object currency) =>
'Invalid $input. $input can\'t be greater than $maxValue $currency',
warnValueShouldBeInRange: (Object input,
Object minValue,
Object currency,
Object maxValue) =>
'$input between $minValue $currency and $maxValue $currency',
actionOK: 'OK',
),
),
],
),
);
},
child: const Text('Numpad'),
),
],
),
);
}
}
1 change: 1 addition & 0 deletions packages/deriv_ui/lib/components/components.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export 'banner/banner.dart';
export 'date_range_picker/date_range_picker.dart';
export 'expandable_bottom_sheet/expandable_bottom_sheet.dart';
export 'numpad/numpad.dart';
export 'form_builder/form_builder.dart';
export 'grouped_list_view/grouped_list_view.dart';
64 changes: 64 additions & 0 deletions packages/deriv_ui/lib/components/numpad/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Numberpad

Number Pad Widget for number input in Deriv Go and Deriv P2P.

## Usage:

The `Numberpad` widget takes quite a few arguments, which are:

- `formatter` (required): A `NumberFormat` that is fetched from the `intl` package. Sets the format of the input text.
- `numberpadType` (required): Either `NumberPadWidgetType.singleInput` for a single text field, or `NumberPadWidgetType.doubleInput` for two text fields.
- `label` (required): `NumberPadLabel` is a class that contains a list of necessary strings basid on current localizaiton:

- `semanticNumberPadBottomSheetHandle`: Description for the `semanticsLabel` property of the handle SVG at the top.
- `actionOK`: The text on the `Ok` button in any open dialoge.
- `warnValueCantBeLessThan`: Warning when the entered value is less that minimum amount.
- `warnValueCantBeGreaterThan`: Warning when the entered value is greater that minimum amount.
- `warnDoubleInputValueCantBeLessThan`: Warning when input is invalid because it can't be less than minimum amount.
- `warnDoubleInputValueCantBeGreaterThan`: Warning when input is invalid because it can't be greater than minimum amount.
- `warnValueShouldBeInRange`: Warning when value is not in valid range.

- `currency`: Sets the currency of the number pad.
- `firstInputTite`: Title of the first textfield.
- `secondInputTitle`: Title of the second textfield. (If input type is doubleInput)
- `manInputLength`: Maximum possible input characters for input values.
- `firstInputInitialValue`: The initial value of first text field.
- `secondInputInitialValue`: The initial value of second text field.
- `firstInputMinimumValue`: The minimum value in the first text field.
- `secondInputMinimumValue`: The minimum value in the second text field.
- `firstInputMaximumValue`: The maximum value int the first text field.
- `secondInputMaximumValue`: The maximum value int the second text field.
- `onOpen`: VoidCallback whem NumberPad opens.
- `onClose`: Callback when NumberPad closes. Takes 3 arguments (NumberadWidgetType, NumberPadCloseType, NumberPadData).
- `NumberPadWidgetType`: Current `NumberPadWidgetType`.
- `NumberPadCloseType`: `NumberPadCloseType.pressOK` for when the user clicks on the OK button to close numberPad widget. Or `NumberPadCloseType.clickOutsideView` for when the user clicks anywhere outside the widget to dismiss the NumberPad widget.
- `NumberPadData`: A wrapper around the values in the first and second input text fields.
- `currentFocus`: When there are two text fields, you can choose which one has initial focus, either `NumberPadInputFocus.firstInputField` for a the first text field, or `NumberPadInputFocus.secondInputField` for the second text field.
- `dialogeDescription`: The description text displayed when the info icon is clicked.
- `headerLeading`: The leading widget on the header of the Numberpad.

## Example

```dart
NumberPad(
formatter: NumberFormat.decimalPattern(),
numberPadType: NumberPadWidgetType.singleInput,
firstInputTitle: context.localization.labelTakeProfit,
firstInputInitialValue: initialTPValue,
secondInputTitle: context.localization.labelStopLoss,
secondInputInitialValue: initialSLValue,
currency: currency,
onClose: (
NumberPadWidgetType type,
NumberPadCloseType closeType,
NumberPadData result,
) async {
if (closeType == NumberPadCloseType.pressOK) {
widget.onTakeProfitStopLossChanged?.call(
result.firstInputValue ?? -1,
result.secondInputValue ?? -1,
);
}
},
),
```
7 changes: 7 additions & 0 deletions packages/deriv_ui/lib/components/numpad/core/assets.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// ignore_for_file: public_member_api_docs

// This file contains all assets to have a single source of all resources

// Icons
const String handleIcon = 'assets/icons/ic_handle.svg';
const String swapIcon = 'assets/icons/ic_currency_swap.svg';
5 changes: 5 additions & 0 deletions packages/deriv_ui/lib/components/numpad/core/core.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export 'helpers/helpers.dart';
export 'widgets/widgets.dart';
export 'assets.dart';
export 'enums.dart';
export 'exchange_notifier.dart';
31 changes: 31 additions & 0 deletions packages/deriv_ui/lib/components/numpad/core/enums.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@


/// Indicates the number of inputs in the NumberPad widget,
/// between one or two inputs.
enum NumberPadWidgetType {
/// Has one input with a title at the top of the view.
singleInput,

/// Has two inputs with a title at the top of each input.
doubleInput,
}

/// Indicates which input field should be focused when
/// [NumberPadWidgetType] is double input.
enum NumberPadInputFocus {
/// Focuses on the first input field.
firstInputField,

/// Focuses on the second input field.
secondInputField,
}

/// Indicates how NumberPad widget is closed
enum NumberPadCloseType {
/// When the user clicked on the OK button to close numberPad widget
pressOK,

/// when the user clicked anywhere outside the widget
/// to dismiss the NumberPad widget
clickOutsideView,
}
Loading

0 comments on commit 3802e2e

Please sign in to comment.