mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-04-25 07:07:32 -04:00
chore: single selection field
This commit is contained in:
parent
d2080a6c03
commit
55b888e364
9 changed files with 333 additions and 59 deletions
|
@ -163,7 +163,10 @@
|
||||||
"dateFormatUS": "Month/Month/Day",
|
"dateFormatUS": "Month/Month/Day",
|
||||||
"timeFormat": " Time format",
|
"timeFormat": " Time format",
|
||||||
"timeFormatTwelveHour": "12 hour",
|
"timeFormatTwelveHour": "12 hour",
|
||||||
"timeFormatTwentyFourHour": "24 hour"
|
"timeFormatTwentyFourHour": "24 hour",
|
||||||
|
"addSelectOption": "Add an option",
|
||||||
|
"optionTitle": "Options",
|
||||||
|
"addOption": "Add option"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flowy_sdk/log.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'dart:async';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
|
||||||
|
part 'option_pannel_bloc.freezed.dart';
|
||||||
|
|
||||||
|
class OptionPannelBloc extends Bloc<OptionPannelEvent, OptionPannelState> {
|
||||||
|
OptionPannelBloc({required List<SelectOption> options}) : super(OptionPannelState.initial(options)) {
|
||||||
|
on<OptionPannelEvent>(
|
||||||
|
(event, emit) async {
|
||||||
|
await event.map(
|
||||||
|
createOption: (_CreateOption value) async {
|
||||||
|
emit(state.copyWith(isAddingOption: false));
|
||||||
|
},
|
||||||
|
beginAddingOption: (_BeginAddingOption value) {
|
||||||
|
emit(state.copyWith(isAddingOption: true));
|
||||||
|
},
|
||||||
|
endAddingOption: (_EndAddingOption value) {
|
||||||
|
emit(state.copyWith(isAddingOption: false));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class OptionPannelEvent with _$OptionPannelEvent {
|
||||||
|
const factory OptionPannelEvent.createOption(String optionName) = _CreateOption;
|
||||||
|
const factory OptionPannelEvent.beginAddingOption() = _BeginAddingOption;
|
||||||
|
const factory OptionPannelEvent.endAddingOption() = _EndAddingOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class OptionPannelState with _$OptionPannelState {
|
||||||
|
const factory OptionPannelState({
|
||||||
|
required List<SelectOption> options,
|
||||||
|
required bool isAddingOption,
|
||||||
|
}) = _OptionPannelState;
|
||||||
|
|
||||||
|
factory OptionPannelState.initial(List<SelectOption> options) => OptionPannelState(
|
||||||
|
options: options,
|
||||||
|
isAddingOption: false,
|
||||||
|
);
|
||||||
|
}
|
|
@ -30,6 +30,10 @@ class _GridRowWidgetState extends State<GridRowWidget> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider.value(
|
return BlocProvider.value(
|
||||||
value: _rowBloc,
|
value: _rowBloc,
|
||||||
|
child: MouseRegion(
|
||||||
|
cursor: SystemMouseCursors.click,
|
||||||
|
onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()),
|
||||||
|
onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()),
|
||||||
child: BlocBuilder<RowBloc, RowState>(
|
child: BlocBuilder<RowBloc, RowState>(
|
||||||
buildWhen: (p, c) => p.rowHeight != c.rowHeight,
|
buildWhen: (p, c) => p.rowHeight != c.rowHeight,
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
|
@ -46,31 +50,8 @@ class _GridRowWidgetState extends State<GridRowWidget> {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
// return BlocProvider.value(
|
|
||||||
// value: _rowBloc,
|
|
||||||
// child: MouseRegion(
|
|
||||||
// cursor: SystemMouseCursors.click,
|
|
||||||
// onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()),
|
|
||||||
// onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()),
|
|
||||||
// child: BlocBuilder<RowBloc, RowState>(
|
|
||||||
// buildWhen: (p, c) => p.rowHeight != c.rowHeight,
|
|
||||||
// builder: (context, state) {
|
|
||||||
// return SizedBox(
|
|
||||||
// height: _rowBloc.state.rowHeight,
|
|
||||||
// child: Row(
|
|
||||||
// crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
// children: const [
|
|
||||||
// _RowLeading(),
|
|
||||||
// _RowCells(),
|
|
||||||
// _RowTrailing(),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -20,7 +20,7 @@ class CreateFieldPannel extends FlowyOverlayDelegate {
|
||||||
FlowyOverlay.of(context).insertWithAnchor(
|
FlowyOverlay.of(context).insertWithAnchor(
|
||||||
widget: OverlayContainer(
|
widget: OverlayContainer(
|
||||||
child: _CreateFieldPannelWidget(_createFieldBloc),
|
child: _CreateFieldPannelWidget(_createFieldBloc),
|
||||||
constraints: BoxConstraints.loose(const Size(220, 400)),
|
constraints: BoxConstraints.loose(const Size(220, 500)),
|
||||||
),
|
),
|
||||||
identifier: identifier(),
|
identifier: identifier(),
|
||||||
anchorContext: context,
|
anchorContext: context,
|
||||||
|
|
|
@ -49,7 +49,9 @@ class FieldTypeList extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
return ListView.separated(
|
return SizedBox(
|
||||||
|
width: 140,
|
||||||
|
child: ListView.separated(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
controller: ScrollController(),
|
controller: ScrollController(),
|
||||||
itemCount: cells.length,
|
itemCount: cells.length,
|
||||||
|
@ -60,6 +62,7 @@ class FieldTypeList extends StatelessWidget {
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
return cells[index];
|
return cells[index];
|
||||||
},
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ class NumberFormatItem extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = context.watch<AppTheme>();
|
final theme = context.watch<AppTheme>();
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 26,
|
height: GridSize.typeOptionItemHeight,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
text: FlowyText.medium(format.title(), fontSize: 12),
|
text: FlowyText.medium(format.title(), fontSize: 12),
|
||||||
hoverColor: theme.hover,
|
hoverColor: theme.hover,
|
||||||
|
|
|
@ -1,9 +1,20 @@
|
||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
|
import 'package:app_flowy/workspace/application/grid/field/type_option/option_pannel_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/field/type_option/selection_bloc.dart';
|
import 'package:app_flowy/workspace/application/grid/field/type_option/selection_bloc.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart';
|
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart';
|
||||||
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
|
|
||||||
|
import 'widget.dart';
|
||||||
|
|
||||||
class SingleSelectTypeOptionBuilder extends TypeOptionBuilder {
|
class SingleSelectTypeOptionBuilder extends TypeOptionBuilder {
|
||||||
SingleSelectTypeOption typeOption;
|
SingleSelectTypeOption typeOption;
|
||||||
|
@ -12,17 +23,18 @@ class SingleSelectTypeOptionBuilder extends TypeOptionBuilder {
|
||||||
: typeOption = SingleSelectTypeOption.fromBuffer(typeOptionData);
|
: typeOption = SingleSelectTypeOption.fromBuffer(typeOptionData);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? get customWidget => const SingleSelectTypeOptionWidget();
|
Widget? get customWidget => SingleSelectTypeOptionWidget(typeOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
class SingleSelectTypeOptionWidget extends TypeOptionWidget {
|
class SingleSelectTypeOptionWidget extends TypeOptionWidget {
|
||||||
const SingleSelectTypeOptionWidget({Key? key}) : super(key: key);
|
final SingleSelectTypeOption typeOption;
|
||||||
|
const SingleSelectTypeOptionWidget(this.typeOption, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => getIt<SelectionTypeOptionBloc>(),
|
create: (context) => getIt<SelectionTypeOptionBloc>(),
|
||||||
child: Container(height: 100, color: Colors.yellow),
|
child: OptionPannel(options: typeOption.options),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,17 +46,165 @@ class MultiSelectTypeOptionBuilder extends TypeOptionBuilder {
|
||||||
: typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData);
|
: typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? get customWidget => const MultiSelectTypeOptionWidget();
|
Widget? get customWidget => MultiSelectTypeOptionWidget(typeOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiSelectTypeOptionWidget extends TypeOptionWidget {
|
class MultiSelectTypeOptionWidget extends TypeOptionWidget {
|
||||||
const MultiSelectTypeOptionWidget({Key? key}) : super(key: key);
|
final MultiSelectTypeOption typeOption;
|
||||||
|
const MultiSelectTypeOptionWidget(this.typeOption, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => getIt<SelectionTypeOptionBloc>(),
|
create: (context) => getIt<SelectionTypeOptionBloc>(),
|
||||||
child: Container(height: 100, color: Colors.blue),
|
child: OptionPannel(options: typeOption.options),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class OptionPannel extends StatelessWidget {
|
||||||
|
final List<SelectOption> options;
|
||||||
|
const OptionPannel({required this.options, Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) => OptionPannelBloc(options: options),
|
||||||
|
child: BlocBuilder<OptionPannelBloc, OptionPannelState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
List<Widget> children = [const OptionTitle()];
|
||||||
|
if (state.isAddingOption) {
|
||||||
|
children.add(const _AddOptionTextField());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.options.isEmpty && !state.isAddingOption) {
|
||||||
|
children.add(const _AddOptionButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.options.isNotEmpty) {
|
||||||
|
children.add(const _OptionList());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Column(children: children);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OptionTitle extends StatelessWidget {
|
||||||
|
const OptionTitle({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = context.watch<AppTheme>();
|
||||||
|
|
||||||
|
return BlocBuilder<OptionPannelBloc, OptionPannelState>(
|
||||||
|
buildWhen: (previous, current) => previous.options.length != current.options.length,
|
||||||
|
builder: (context, state) {
|
||||||
|
List<Widget> children = [FlowyText.medium(LocaleKeys.grid_field_optionTitle.tr(), fontSize: 12)];
|
||||||
|
|
||||||
|
if (state.options.isNotEmpty && state.isAddingOption == false) {
|
||||||
|
children.add(FlowyButton(
|
||||||
|
text: FlowyText.medium(LocaleKeys.grid_field_addOption.tr(), fontSize: 12),
|
||||||
|
hoverColor: theme.hover,
|
||||||
|
onTap: () {
|
||||||
|
context.read<OptionPannelBloc>().add(const OptionPannelEvent.beginAddingOption());
|
||||||
|
},
|
||||||
|
rightIcon: svg("grid/more", color: theme.iconColor),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
height: GridSize.typeOptionItemHeight,
|
||||||
|
child: Row(children: children),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _OptionList extends StatelessWidget {
|
||||||
|
const _OptionList({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<OptionPannelBloc, OptionPannelState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
final optionItems = state.options.map((option) {
|
||||||
|
return _OptionItem(option: option);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
width: 120,
|
||||||
|
child: ListView.separated(
|
||||||
|
shrinkWrap: true,
|
||||||
|
controller: ScrollController(),
|
||||||
|
separatorBuilder: (context, index) {
|
||||||
|
return VSpace(GridSize.typeOptionSeparatorHeight);
|
||||||
|
},
|
||||||
|
itemCount: optionItems.length,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return optionItems[index];
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _OptionItem extends StatelessWidget {
|
||||||
|
final SelectOption option;
|
||||||
|
const _OptionItem({required this.option, Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = context.watch<AppTheme>();
|
||||||
|
return SizedBox(
|
||||||
|
height: GridSize.typeOptionItemHeight,
|
||||||
|
child: FlowyButton(
|
||||||
|
text: FlowyText.medium(option.name, fontSize: 12),
|
||||||
|
hoverColor: theme.hover,
|
||||||
|
onTap: () {},
|
||||||
|
rightIcon: svg("grid/more", color: theme.iconColor),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AddOptionButton extends StatelessWidget {
|
||||||
|
const _AddOptionButton({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = context.watch<AppTheme>();
|
||||||
|
return SizedBox(
|
||||||
|
height: GridSize.typeOptionItemHeight,
|
||||||
|
child: FlowyButton(
|
||||||
|
text: FlowyText.medium(LocaleKeys.grid_field_addSelectOption.tr(), fontSize: 12),
|
||||||
|
hoverColor: theme.hover,
|
||||||
|
onTap: () {
|
||||||
|
context.read<OptionPannelBloc>().add(const OptionPannelEvent.beginAddingOption());
|
||||||
|
},
|
||||||
|
leftIcon: svg("home/add", color: theme.iconColor),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AddOptionTextField extends StatelessWidget {
|
||||||
|
const _AddOptionTextField({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return NameTextField(
|
||||||
|
name: "",
|
||||||
|
onCanceled: () {
|
||||||
|
context.read<OptionPannelBloc>().add(const OptionPannelEvent.endAddingOption());
|
||||||
|
},
|
||||||
|
onDone: (optionName) {
|
||||||
|
context.read<OptionPannelBloc>().add(OptionPannelEvent.createOption(optionName));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
import 'package:flowy_infra/theme.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
|
class NameTextField extends StatefulWidget {
|
||||||
|
final void Function(String) onDone;
|
||||||
|
final void Function() onCanceled;
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
const NameTextField({
|
||||||
|
required this.name,
|
||||||
|
required this.onDone,
|
||||||
|
required this.onCanceled,
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<NameTextField> createState() => _NameTextFieldState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NameTextFieldState extends State<NameTextField> {
|
||||||
|
late FocusNode _focusNode;
|
||||||
|
late TextEditingController _controller;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_focusNode = FocusNode();
|
||||||
|
_controller = TextEditingController(text: widget.name);
|
||||||
|
|
||||||
|
_focusNode.addListener(notifyDidEndEditing);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = context.watch<AppTheme>();
|
||||||
|
return RoundedInputField(
|
||||||
|
controller: _controller,
|
||||||
|
focusNode: _focusNode,
|
||||||
|
height: 36,
|
||||||
|
style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500),
|
||||||
|
normalBorderColor: theme.shader4,
|
||||||
|
errorBorderColor: theme.red,
|
||||||
|
focusBorderColor: theme.main1,
|
||||||
|
cursorColor: theme.main1,
|
||||||
|
onChanged: (text) {
|
||||||
|
print(text);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_focusNode.removeListener(notifyDidEndEditing);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void notifyDidEndEditing() {
|
||||||
|
if (_controller.text.isEmpty) {
|
||||||
|
// widget.onCanceled();
|
||||||
|
} else {
|
||||||
|
widget.onDone(_controller.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,8 @@ class RoundedInputField extends StatefulWidget {
|
||||||
final EdgeInsets padding;
|
final EdgeInsets padding;
|
||||||
final EdgeInsets contentPadding;
|
final EdgeInsets contentPadding;
|
||||||
final double height;
|
final double height;
|
||||||
|
final FocusNode? focusNode;
|
||||||
|
final TextEditingController? controller;
|
||||||
|
|
||||||
const RoundedInputField({
|
const RoundedInputField({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
@ -39,6 +41,8 @@ class RoundedInputField extends StatefulWidget {
|
||||||
this.padding = EdgeInsets.zero,
|
this.padding = EdgeInsets.zero,
|
||||||
this.contentPadding = const EdgeInsets.symmetric(horizontal: 10),
|
this.contentPadding = const EdgeInsets.symmetric(horizontal: 10),
|
||||||
this.height = 48,
|
this.height = 48,
|
||||||
|
this.focusNode,
|
||||||
|
this.controller,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -71,7 +75,9 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||||
padding: widget.padding,
|
padding: widget.padding,
|
||||||
height: widget.height,
|
height: widget.height,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
|
controller: widget.controller,
|
||||||
initialValue: widget.initialValue,
|
initialValue: widget.initialValue,
|
||||||
|
focusNode: widget.focusNode,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
inputText = value;
|
inputText = value;
|
||||||
if (widget.onChanged != null) {
|
if (widget.onChanged != null) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue