Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
06f725d
first commit
Tayebsed93 Sep 30, 2025
3362f11
feat : add finish password input
Tayebsed93 Oct 3, 2025
a483959
review : decoration / code generator / outlined
Tayebsed93 Oct 7, 2025
e383c9a
review : keys and fix trailing icon
Tayebsed93 Oct 8, 2025
99c260c
review : max lines and component list
Tayebsed93 Oct 8, 2025
5a4abb7
review dart code generator
Tayebsed93 Oct 8, 2025
5fbe909
review : add no doc l10n
Tayebsed93 Oct 9, 2025
815ddad
review : keys l10n
Tayebsed93 Oct 10, 2025
6dff48e
review : loader status
Tayebsed93 Oct 20, 2025
6940a8e
review : prefix status
Tayebsed93 Oct 20, 2025
df4fa2b
fix : prefix and suffix status like password input
Tayebsed93 Oct 20, 2025
4039716
fix: build function Textfield
Tayebsed93 Oct 27, 2025
df16617
chore : add customizable textfield
Tayebsed93 Oct 29, 2025
ce37daa
fix: order component name alphabetic
Tayebsed93 Nov 4, 2025
0f2776d
review: accessibility, token text color
nouha06 Nov 4, 2025
50c03cc
review: accessibility
nouha06 Nov 5, 2025
f0c5697
review : order component
Tayebsed93 Nov 5, 2025
123475d
loader when placeholder and typing
Tayebsed93 Nov 5, 2025
9a3c69c
Merge branch 'develop' into 397-create-component---password-input
Tayebsed93 Nov 5, 2025
9843642
Merge branch 'develop' into 397-create-component---password-input
Tayebsed93 Nov 6, 2025
3eb07b0
review: loader state disabled edditing
Tayebsed93 Nov 6, 2025
e33af20
Merge branch '397-create-component---password-input' of https://githu…
Tayebsed93 Nov 6, 2025
67a0293
review : changelog
Tayebsed93 Nov 6, 2025
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
7 changes: 7 additions & 0 deletions NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ ouds-flutter/app/assets/ic_about.svg
ouds-flutter/app/assets/ic_atom.svg
ouds-flutter/app/assets/ic_token.svg
ouds-flutter/app/assets/ic_chip_heart.svg
ouds-flutter/app/assets/ic_delete.svg
ouds-flutter/app/assets/il_tokens_color.svg
ouds-flutter/app/assets/il_tokens_color_dark.svg
ouds-flutter/app/assets/il_tokens_elevation.svg
Expand Down Expand Up @@ -56,6 +57,9 @@ ouds_theme_orange/assets/ic_error.svg
ouds_theme_orange/assets/ic_heart.svg
ouds_theme_orange/assets/ic_bullet_rounded.svg
ouds_theme_orange/assets/ic_important_alert.svg
ouds_theme_orange/assets/ic_password_vision_hide.svg
ouds_theme_orange/assets/ic_password_vision.svg
ouds_theme_orange/assets/ic_password_lock.svg

ouds_theme_sosh/fonts/Roboto-Black.ttf
ouds_theme_sosh/fonts/Roboto-Bold.ttf
Expand Down Expand Up @@ -92,6 +96,9 @@ ouds_theme_sosh/assets/ic_error.svg
ouds_theme_sosh/assets/ic_heart.svg
ouds_theme_sosh/assets/ic_bullet_tag.svg
ouds_theme_sosh/assets/ic_important_alert.svg
ouds_theme_sosh/assets/ic_password_vision_hide.svg
ouds_theme_sosh/assets/ic_password_vision.svg
ouds_theme_sosh/assets/ic_password_lock.svg

ouds_theme_sosh/fonts/Sosh-Black.ttf
ouds_theme_sosh/fonts/Sosh-Bold.ttf
Expand Down
1 change: 1 addition & 0 deletions app/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased](https://github.com/Orange-OpenSource/ouds-flutter/compare/0.5.0...develop)

### Added
- [DemoApp][Library] Create component - `Password Input` ([#397](https://github.com/Orange-OpenSource/ouds-flutter/issues/#397))
- [DemoApp][Library] Create component - `Pin Code Input` ([#307](https://github.com/Orange-OpenSource/ouds-flutter/issues/307))
- [DemoApp][Library] Create component - `Link` ([#46](https://github.com/Orange-OpenSource/ouds-flutter/issues/46))
- [library] Mobile SDK Data Privacy Disclaimer ([#410](https://github.com/Orange-OpenSource/ouds-flutter/issues/#410))
Expand Down
1 change: 1 addition & 0 deletions app/assets/ic_delete.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions app/lib/l10n/gen/ouds_flutter_app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,24 @@ abstract class AppLocalizations {
/// **'Next'**
String get app_components_link_nextLayout_label;

/// No description provided for @app_components_password_input_label.
///
/// In en, this message translates to:
/// **'Password input'**
String get app_components_password_input_label;

/// No description provided for @app_components_password_input_description_text.
///
/// In en, this message translates to:
/// **'A password input is a form field specifically designed to securely capture a user’s confidential password. It masks the characters as they are typed, typically replacing them with dots, in order to protect the input from being read by others nearby. While the primary goal is to enhance privacy and security, the field may also include usability features such as a show/hide password toggle and helper text to guide password creation.'**
String get app_components_password_input_description_text;

/// No description provided for @app_components_password_input_error_label.
///
/// In en, this message translates to:
/// **'Please enter your password.'**
String get app_components_password_input_error_label;

/// No description provided for @app_components_pin_code_input_label.
///
/// In en, this message translates to:
Expand Down
11 changes: 11 additions & 0 deletions app/lib/l10n/gen/ouds_flutter_app_localizations_ar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,17 @@ class AppLocalizationsAr extends AppLocalizations {
@override
String get app_components_link_nextLayout_label => 'التالي';

@override
String get app_components_password_input_label => 'كلمة المرور';

@override
String get app_components_password_input_description_text =>
'حقل إدخال كلمة المرور هو حقل نموذج مصمم خصيصًا لالتقاط كلمة مرور المستخدم بسرية. يقوم بإخفاء الأحرف أثناء الكتابة، عادةً باستبدالها بنقاط، لحماية الإدخال من قراءته من قبل الآخرين القريبين. بينما الهدف الأساسي هو تعزيز الخصوصية والأمان، قد يتضمن الحقل أيضًا ميزات سهولة الاستخدام مثل تبديل إظهار/إخفاء كلمة المرور ونص المساعدة لتوجيه إنشاء كلمة المرور.';

@override
String get app_components_password_input_error_label =>
'يرجى إدخال كلمة المرور الخاصة بك.';

@override
String get app_components_pin_code_input_label => 'إدخال الرقم السري الشخصي';

Expand Down
11 changes: 11 additions & 0 deletions app/lib/l10n/gen/ouds_flutter_app_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,17 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get app_components_link_nextLayout_label => 'Next';

@override
String get app_components_password_input_label => 'Password input';

@override
String get app_components_password_input_description_text =>
'A password input is a form field specifically designed to securely capture a user’s confidential password. It masks the characters as they are typed, typically replacing them with dots, in order to protect the input from being read by others nearby. While the primary goal is to enhance privacy and security, the field may also include usability features such as a show/hide password toggle and helper text to guide password creation.';

@override
String get app_components_password_input_error_label =>
'Please enter your password.';

@override
String get app_components_pin_code_input_label => 'Pin code input';

Expand Down
6 changes: 6 additions & 0 deletions app/lib/l10n/ouds_flutter_ar.arb
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@
"app_components_link_backLayout_label": "عوده",
"app_components_link_nextLayout_label": "التالي",

"@_components_password_input": {},
"app_components_password_input_label": "كلمة المرور",
"app_components_password_input_description_text": "حقل إدخال كلمة المرور هو حقل نموذج مصمم خصيصًا لالتقاط كلمة مرور المستخدم بسرية. يقوم بإخفاء الأحرف أثناء الكتابة، عادةً باستبدالها بنقاط، لحماية الإدخال من قراءته من قبل الآخرين القريبين. بينما الهدف الأساسي هو تعزيز الخصوصية والأمان، قد يتضمن الحقل أيضًا ميزات سهولة الاستخدام مثل تبديل إظهار/إخفاء كلمة المرور ونص المساعدة لتوجيه إنشاء كلمة المرور.",
"app_components_password_input_error_label": "يرجى إدخال كلمة المرور الخاصة بك.",


"@_components_pin_code_input": {},
"app_components_pin_code_input_label": "إدخال الرقم السري الشخصي",
"app_components_pin_code_input_description_text": "حقل إدخال الرقم السري الشخصي هو حقل مخصص لإدخال رموز رقمية قصيرة وثابتة الطول، يُستخدم عادةً للمصادقة أو لتأكيد العمليات، مثل الرقم السري الشخصي المكوَّن من 4 أو 6 أو 8 أرقام.",
Expand Down
5 changes: 5 additions & 0 deletions app/lib/l10n/ouds_flutter_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@
"app_components_link_backLayout_label": "Back",
"app_components_link_nextLayout_label": "Next",

"@_components_password_input": {},
"app_components_password_input_label": "Password input",
"app_components_password_input_description_text": "A password input is a form field specifically designed to securely capture a user’s confidential password. It masks the characters as they are typed, typically replacing them with dots, in order to protect the input from being read by others nearby. While the primary goal is to enhance privacy and security, the field may also include usability features such as a show/hide password toggle and helper text to guide password creation.",
"app_components_password_input_error_label": "Please enter your password.",

"@_components_pin_code_input": {},
"app_components_pin_code_input_label": "Pin code input",
"app_components_pin_code_input_description_text": "A PIN code input is a specialized form field used to capture short, fixed-length numeric codes, typically for authentication or confirmation purposes, such as a 4, 6 or 8-digit personal identification number (PIN).",
Expand Down
54 changes: 33 additions & 21 deletions app/lib/ui/components/components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ import 'package:ouds_core/components/button/ouds_button.dart';
import 'package:ouds_core/components/checkbox/ouds_checkbox.dart';
import 'package:ouds_core/components/chip/ouds_filter_chip.dart';
import 'package:ouds_core/components/divider/ouds_divider.dart';
import 'package:ouds_core/components/form_input/internal/ouds_form_input_decoration.dart';
import 'package:ouds_core/components/form_input/ouds_text_input.dart';
import 'package:ouds_core/components/form_input/password_input/ouds_password_input.dart';
import 'package:ouds_core/components/form_input/password_input/ouds_password_input_decoration.dart';
import 'package:ouds_core/components/link/ouds_link.dart';
import 'package:ouds_core/components/pin_code_input/digit_input/ouds_digit_input.dart';
import 'package:ouds_core/components/pin_code_input/ouds_pin_code_input.dart';
import 'package:ouds_core/components/radio_button/ouds_radio_button.dart';
import 'package:ouds_core/components/switch/ouds_switch.dart';
import 'package:ouds_core/components/tag/ouds_tag.dart';
import 'package:ouds_core/components/text_input/ouds_text_input.dart';
import 'package:ouds_flutter_demo/l10n/app_localizations.dart';
import 'package:ouds_flutter_demo/ui/components/badge/badge_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/button/button_demo_screen.dart';
Expand All @@ -35,16 +38,17 @@ import 'package:ouds_flutter_demo/ui/components/chip/chip_suggestion_demo_screen
import 'package:ouds_flutter_demo/ui/components/component_container.dart';
import 'package:ouds_flutter_demo/ui/components/component_entities.dart';
import 'package:ouds_flutter_demo/ui/components/divider/divider_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/form_input/password_input/password_input_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/form_input/text_input/text_input_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/link/link_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/pin_code_input/pin_code_input_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/radio_button/radio_button_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/radio_button/radio_button_item_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/switch/switch_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/switch/switch_item_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/tag/tag_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/tag/tag_input_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/pin_code_input/pin_code_input_demo_screen.dart';
import 'package:ouds_flutter_demo/ui/components/text_input/text_input_demo_screen.dart';
import 'package:ouds_theme_contract/ouds_theme.dart';
import 'package:ouds_flutter_demo/ui/components/link/link_demo_screen.dart';

List<Component> components(BuildContext context) {
final theme = OudsTheme.of(context);
Expand Down Expand Up @@ -175,31 +179,39 @@ List<Component> components(BuildContext context) {
context.l10n.app_components_link_description_text,
LinkDemoScreen(),
),
Component(
context.l10n.app_components_password_input_label,
ComponentContainer(
child: Padding(
padding: const EdgeInsetsGeometry.directional(start: 20.0, end: 20.0),
child: Center(
child: OudsPasswordInput(
decoration: OudsPasswordInputDecoration(
labelText: "Password",
helperText: "Your password must be between 8 and 20 characters long.",
),
),
),
),
),
context.l10n.app_components_password_input_description_text,
PasswordInputDemoScreen(),
),
Component(
context.l10n.app_components_pin_code_input_label,
ComponentContainer(
child: Padding(
padding: const EdgeInsetsGeometry.directional(start: 10.0, end: 10.0),
child: OudsPinCodeInput(
controllers: [
TextEditingController(
text: "1"
),
TextEditingController(
text: "1"
),
TextEditingController(
text: "1"
),
TextEditingController(text: "1"),
TextEditingController(text: "1"),
TextEditingController(text: "1"),
TextEditingController(
text: "",
),
TextEditingController(
text: ""
),
TextEditingController(
text: ""
),
TextEditingController(text: ""),
TextEditingController(text: ""),
],
digitInputDecoration: OudsDigitInputDecoration(
hintText: '-',
Expand Down Expand Up @@ -286,8 +298,8 @@ List<Component> components(BuildContext context) {
child: Padding(
padding: const EdgeInsetsGeometry.directional(start: 20.0, end: 20.0),
child: Center(
child: OudsTextInput(
decoration: OudsInputDecoration(labelText: "Label", helperText: "Helper text."),
child: OudsTextField(
decoration: OudsInputDecoration(labelText: "Label", helperText: "Helper text.", outlined: false),
),
),
),
Expand Down
117 changes: 117 additions & 0 deletions app/lib/ui/components/form_input/form_fields_code_generator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* // Software Name: OUDS Flutter
* // SPDX-FileCopyrightText: Copyright (c) Orange SA
* // SPDX-License-Identifier: MIT
* //
* // This software is distributed under the MIT license,
* // the text of which is available at https://opensource.org/license/MIT/
* // or see the "LICENSE" file for more details.
* //
* // Software description: Flutter library of reusable graphical components
* //
*/
import 'package:flutter/material.dart';
import 'package:ouds_flutter_demo/ui/components/form_input/form_fields_customization.dart';
import 'package:ouds_flutter_demo/ui/components/form_input/form_fields_enum.dart';

class FormFieldsCodeGenerator {
static String updateCode(BuildContext context, FormFieldsTypeEnum inputTypeEnum) {
final FormFieldsCustomizationState? state = FormFieldsCustomization.of(context);
String boolPropertiesCode = generateBoolPropertiesCode(state, inputTypeEnum);
List<String> codeParts;

String decoration = decorationCode(
context,
state?.labelText ?? '',
state?.suffixText ?? '',
state?.prefixText ?? '',
state?.placeholderText ?? '',
state?.helperText ?? '',
state?.hasTrailingIcon,
state?.hasLeadingIcon,
state?.hasLoader ?? false,
state?.hasOutlined ?? false,
state?.hasError == true,
inputTypeEnum,
);

switch (inputTypeEnum) {
case FormFieldsTypeEnum.textInput:
codeParts = ["OudsTextField(", if (boolPropertiesCode.trim().isNotEmpty) boolPropertiesCode, decoration, "),"];
break;
case FormFieldsTypeEnum.phoneNumberInput:
codeParts = ["OudsPhoneNumberInput(", if (boolPropertiesCode.trim().isNotEmpty) boolPropertiesCode, decoration, "),"];
break;
case FormFieldsTypeEnum.passwordInput:
codeParts = ["OudsPasswordInput(", if (boolPropertiesCode.trim().isNotEmpty) boolPropertiesCode, decoration, "),"];
break;
}

return codeParts.join("\n");
}

static String generateBoolPropertiesCode(FormFieldsCustomizationState? state, FormFieldsTypeEnum inputTypeEnum) {
if (state == null) return "";

List<String> lines = [];

if (state.hasEnabled != true) {
lines.add('enabled: false,');
}

if (state.hasReadOnly == true) {
lines.add('readOnly: true,');
}

if (state.hasCountrySelector == true && inputTypeEnum == FormFieldsTypeEnum.phoneNumberInput) {
lines.add('countrySelector: CountrySelector(countryFilter:\n CountryFilter.custom,\n codes: ["fr", "tn", "us"],\n onCountryChanged: (country) {},\n ),');
}

return lines.join("\n");
}

static String decorationCode(
BuildContext context,
String label,
String suffix,
String prefix,
String hintText,
String helperText,
bool? suffixIcon,
bool? prefixIcon,
bool hasLoader,
bool? hasOutlined,
bool hasError,
FormFieldsTypeEnum inputTypeEnum,
) {
List<String> lines = [];

if (hasOutlined == true) lines.add(' outlined: true,');
if (label.trim().isNotEmpty) lines.add(' labelText: "$label",');
if (suffix.trim().isNotEmpty) lines.add(' suffix: "$suffix",');
if (prefix.trim().isNotEmpty) lines.add(' prefix: "$prefix",');
if (hintText.trim().isNotEmpty) lines.add(' hintText: "$hintText",');
if (helperText.trim().isNotEmpty) lines.add(' helperText: "$helperText",');
if (hasLoader) lines.add(' loader: true,');

String decorationClass = "OudsInputDecoration";

switch (inputTypeEnum) {
case FormFieldsTypeEnum.phoneNumberInput:
break;
case FormFieldsTypeEnum.passwordInput:
decorationClass = "OudsPasswordInputDecoration";
if (prefixIcon == true) lines.add(" prefixIcon: true,");
if (hasError) lines.add(' errorText: "Please enter your password.",');
break;
default:
if (suffixIcon == true) lines.add(" suffixIcon: 'assets/ic_heart.svg',\n onSuffixPressed: () {},");
if (prefixIcon == true) lines.add(" prefixIcon: 'assets/ic_heart.svg',");
if (hasError) lines.add(' errorText: "This field can’t..",');
}

if (lines.isEmpty) return "decoration: $decorationClass(),";

return "decoration: $decorationClass(\n${lines.join("\n")}\n ),";
}
}
Loading
Loading