diff --git a/examples/stac_gallery/assets/json/dropdown_menu_view_example.json b/examples/stac_gallery/assets/json/dropdown_menu_view_example.json new file mode 100644 index 00000000..1859ba16 --- /dev/null +++ b/examples/stac_gallery/assets/json/dropdown_menu_view_example.json @@ -0,0 +1,65 @@ +{ + "type": "scaffold", + "appBar": { + "type": "appBar", + "title": { + "type": "text", + "data": "Stac DropDown" + } + }, + "body": { + "type": "column", + "children": [ + { + "type": "dropdownMenu", + "leadingIcon": { + "type": "icon", + "iconType": "material", + "icon": "arrow_downward", + "size": 32 + }, + "trailingIcon": { + "type": "icon", + "iconType": "material", + "icon": "double_arrow", + "size": 32 + }, + "initialSelection": "b", + "dropdownMenuEntries": [ + { + "label": "A", + "value": "a", + "leadingIcon": { + "type": "icon", + "iconType": "material", + "icon": "arrow_downward_sharp", + "size": 32 + }, + "trailingIcon": { + "type": "icon", + "iconType": "material", + "icon": "arrow_forward_ios", + "size": 32 + } + }, + { + "label": "B", + "value": "b", + "leadingIcon": { + "type": "icon", + "iconType": "material", + "icon": "arrow_downward_sharp", + "size": 32 + }, + "trailingIcon": { + "type": "icon", + "iconType": "material", + "icon": "arrow_forward_ios", + "size": 32 + } + } + ] + } + ] + } +} \ No newline at end of file diff --git a/examples/stac_gallery/assets/json/home_screen.json b/examples/stac_gallery/assets/json/home_screen.json index e8fe6286..54668640 100644 --- a/examples/stac_gallery/assets/json/home_screen.json +++ b/examples/stac_gallery/assets/json/home_screen.json @@ -1282,5 +1282,27 @@ "assetPath": "assets/json/dynamic_list_view_example.json" } } + }, + { + "type": "listTile", + "leading": { + "type": "icon", + "icon": "api" + }, + "title": { + "type": "text", + "data": "Stac DropDown Menu" + }, + "subtitle": { + "type": "text", + "data": "Drop down menu to select items" + }, + "onTap": { + "actionType": "navigate", + "widgetJson": { + "type": "exampleScreen", + "assetPath": "assets/json/dropdown_menu_view_example.json" + } + } } ] \ No newline at end of file diff --git a/packages/stac/lib/src/framework/stac.dart b/packages/stac/lib/src/framework/stac.dart index 4e28a9e5..0933bd49 100644 --- a/packages/stac/lib/src/framework/stac.dart +++ b/packages/stac/lib/src/framework/stac.dart @@ -9,6 +9,7 @@ import 'package:stac/src/action_parsers/stac_network_request/stac_network_reques import 'package:stac/src/framework/stac_registry.dart'; import 'package:stac/src/parsers/parsers.dart'; import 'package:stac/src/parsers/stac_custom_scroll_view/stac_custom_scroll_view_parser.dart'; +import 'package:stac/src/parsers/stac_dropdown_menu/stac_dropdown_menu_parser.dart'; import 'package:stac/src/parsers/stac_sliver_app_bar/stac_sliver_app_bar_parser.dart'; import 'package:stac/src/services/stac_network_service.dart'; import 'package:stac/src/utils/log.dart'; @@ -99,6 +100,7 @@ class Stac { const StacFittedBoxParser(), const StacLimitedBoxParser(), const StacDynamicViewParser(), + const StacDropdownMenuParser() ]; static final _actionParsers = [ diff --git a/packages/stac/lib/src/parsers/stac_dropdown_menu/stac_dropdown_menu.dart b/packages/stac/lib/src/parsers/stac_dropdown_menu/stac_dropdown_menu.dart new file mode 100644 index 00000000..668cfc56 --- /dev/null +++ b/packages/stac/lib/src/parsers/stac_dropdown_menu/stac_dropdown_menu.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:stac/src/parsers/parsers.dart'; +import 'package:stac/src/parsers/stac_dropdown_menu_entry/stac_dropdown_menu_entry.dart' + show StacDropdownMenuEntry; +import 'package:stac/src/parsers/stac_input_decoration_theme/stac_input_decoration_theme.dart'; +import 'package:stac/src/parsers/stac_offset/stac_offset.dart'; +import 'package:stac/src/utils/text_input_utils.dart'; + +export 'package:stac/src/parsers/stac_container/stac_container_parser.dart'; + +part 'stac_dropdown_menu.freezed.dart'; + +part 'stac_dropdown_menu.g.dart'; + +@freezed +abstract class StacDropdownMenu with _$StacDropdownMenu { + const factory StacDropdownMenu({ + @Default(true) bool enabled, + double? width, + double? menuHeight, + Map? leadingIcon, + Map? trailingIcon, + Map? label, + String? hintText, + String? helperText, + String? errorText, + Map? selectedTrailingIcon, + bool? enableFilter, + bool? enableSearch, + StacTextInputType? keyboardType, + StacTextStyle? textStyle, + @Default(TextAlign.start) TextAlign textAlign, + StacInputDecorationTheme? inputDecorationTheme, + @Default([]) List inputFormatters, + StacOffset? alignmentOffset, + StacEdgeInsets? expandedInsets, + bool? requestFocusOnTap, + dynamic initialSelection, + @Default([]) List dropdownMenuEntries, + @Default(DropdownMenuCloseBehavior.all) + DropdownMenuCloseBehavior? closeBehavior, + }) = _StacDropdownMenu; + + factory StacDropdownMenu.fromJson(Map json) => + _$StacDropdownMenuFromJson(json); +} diff --git a/packages/stac/lib/src/parsers/stac_dropdown_menu/stac_dropdown_menu.freezed.dart b/packages/stac/lib/src/parsers/stac_dropdown_menu/stac_dropdown_menu.freezed.dart new file mode 100644 index 00000000..b0527a94 --- /dev/null +++ b/packages/stac/lib/src/parsers/stac_dropdown_menu/stac_dropdown_menu.freezed.dart @@ -0,0 +1,850 @@ +// dart format width=80 +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'stac_dropdown_menu.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$StacDropdownMenu { + bool get enabled; + double? get width; + double? get menuHeight; + Map? get leadingIcon; + Map? get trailingIcon; + Map? get label; + String? get hintText; + String? get helperText; + String? get errorText; + Map? get selectedTrailingIcon; + bool? get enableFilter; + bool? get enableSearch; + StacTextInputType? get keyboardType; + StacTextStyle? get textStyle; + TextAlign get textAlign; + StacInputDecorationTheme? get inputDecorationTheme; + List get inputFormatters; + StacOffset? get alignmentOffset; + StacEdgeInsets? get expandedInsets; + bool? get requestFocusOnTap; // TextEditingController? controller; + dynamic get initialSelection; // ValueChanged? onSelected; +// FocusNode? focusNode; + List + get dropdownMenuEntries; // FilterCallback? filterCallback; +// SearchCallback? searchCallback, +// +// +// + DropdownMenuCloseBehavior? get closeBehavior; + + /// Create a copy of StacDropdownMenu + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $StacDropdownMenuCopyWith get copyWith => + _$StacDropdownMenuCopyWithImpl( + this as StacDropdownMenu, _$identity); + + /// Serializes this StacDropdownMenu to a JSON map. + Map toJson(); + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is StacDropdownMenu && + (identical(other.enabled, enabled) || other.enabled == enabled) && + (identical(other.width, width) || other.width == width) && + (identical(other.menuHeight, menuHeight) || + other.menuHeight == menuHeight) && + const DeepCollectionEquality() + .equals(other.leadingIcon, leadingIcon) && + const DeepCollectionEquality() + .equals(other.trailingIcon, trailingIcon) && + const DeepCollectionEquality().equals(other.label, label) && + (identical(other.hintText, hintText) || + other.hintText == hintText) && + (identical(other.helperText, helperText) || + other.helperText == helperText) && + (identical(other.errorText, errorText) || + other.errorText == errorText) && + const DeepCollectionEquality() + .equals(other.selectedTrailingIcon, selectedTrailingIcon) && + (identical(other.enableFilter, enableFilter) || + other.enableFilter == enableFilter) && + (identical(other.enableSearch, enableSearch) || + other.enableSearch == enableSearch) && + (identical(other.keyboardType, keyboardType) || + other.keyboardType == keyboardType) && + (identical(other.textStyle, textStyle) || + other.textStyle == textStyle) && + (identical(other.textAlign, textAlign) || + other.textAlign == textAlign) && + (identical(other.inputDecorationTheme, inputDecorationTheme) || + other.inputDecorationTheme == inputDecorationTheme) && + const DeepCollectionEquality() + .equals(other.inputFormatters, inputFormatters) && + (identical(other.alignmentOffset, alignmentOffset) || + other.alignmentOffset == alignmentOffset) && + (identical(other.expandedInsets, expandedInsets) || + other.expandedInsets == expandedInsets) && + (identical(other.requestFocusOnTap, requestFocusOnTap) || + other.requestFocusOnTap == requestFocusOnTap) && + const DeepCollectionEquality() + .equals(other.initialSelection, initialSelection) && + const DeepCollectionEquality() + .equals(other.dropdownMenuEntries, dropdownMenuEntries) && + (identical(other.closeBehavior, closeBehavior) || + other.closeBehavior == closeBehavior)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hashAll([ + runtimeType, + enabled, + width, + menuHeight, + const DeepCollectionEquality().hash(leadingIcon), + const DeepCollectionEquality().hash(trailingIcon), + const DeepCollectionEquality().hash(label), + hintText, + helperText, + errorText, + const DeepCollectionEquality().hash(selectedTrailingIcon), + enableFilter, + enableSearch, + keyboardType, + textStyle, + textAlign, + inputDecorationTheme, + const DeepCollectionEquality().hash(inputFormatters), + alignmentOffset, + expandedInsets, + requestFocusOnTap, + const DeepCollectionEquality().hash(initialSelection), + const DeepCollectionEquality().hash(dropdownMenuEntries), + closeBehavior + ]); + + @override + String toString() { + return 'StacDropdownMenu(enabled: $enabled, width: $width, menuHeight: $menuHeight, leadingIcon: $leadingIcon, trailingIcon: $trailingIcon, label: $label, hintText: $hintText, helperText: $helperText, errorText: $errorText, selectedTrailingIcon: $selectedTrailingIcon, enableFilter: $enableFilter, enableSearch: $enableSearch, keyboardType: $keyboardType, textStyle: $textStyle, textAlign: $textAlign, inputDecorationTheme: $inputDecorationTheme, inputFormatters: $inputFormatters, alignmentOffset: $alignmentOffset, expandedInsets: $expandedInsets, requestFocusOnTap: $requestFocusOnTap, initialSelection: $initialSelection, dropdownMenuEntries: $dropdownMenuEntries, closeBehavior: $closeBehavior)'; + } +} + +/// @nodoc +abstract mixin class $StacDropdownMenuCopyWith<$Res> { + factory $StacDropdownMenuCopyWith( + StacDropdownMenu value, $Res Function(StacDropdownMenu) _then) = + _$StacDropdownMenuCopyWithImpl; + @useResult + $Res call( + {bool enabled, + double? width, + double? menuHeight, + Map? leadingIcon, + Map? trailingIcon, + Map? label, + String? hintText, + String? helperText, + String? errorText, + Map? selectedTrailingIcon, + bool? enableFilter, + bool? enableSearch, + StacTextInputType? keyboardType, + StacTextStyle? textStyle, + TextAlign textAlign, + StacInputDecorationTheme? inputDecorationTheme, + List inputFormatters, + StacOffset? alignmentOffset, + StacEdgeInsets? expandedInsets, + bool? requestFocusOnTap, + dynamic initialSelection, + List dropdownMenuEntries, + DropdownMenuCloseBehavior? closeBehavior}); + + $StacTextStyleCopyWith<$Res>? get textStyle; + $StacInputDecorationThemeCopyWith<$Res>? get inputDecorationTheme; + $StacOffsetCopyWith<$Res>? get alignmentOffset; + $StacEdgeInsetsCopyWith<$Res>? get expandedInsets; +} + +/// @nodoc +class _$StacDropdownMenuCopyWithImpl<$Res> + implements $StacDropdownMenuCopyWith<$Res> { + _$StacDropdownMenuCopyWithImpl(this._self, this._then); + + final StacDropdownMenu _self; + final $Res Function(StacDropdownMenu) _then; + + /// Create a copy of StacDropdownMenu + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? enabled = null, + Object? width = freezed, + Object? menuHeight = freezed, + Object? leadingIcon = freezed, + Object? trailingIcon = freezed, + Object? label = freezed, + Object? hintText = freezed, + Object? helperText = freezed, + Object? errorText = freezed, + Object? selectedTrailingIcon = freezed, + Object? enableFilter = freezed, + Object? enableSearch = freezed, + Object? keyboardType = freezed, + Object? textStyle = freezed, + Object? textAlign = null, + Object? inputDecorationTheme = freezed, + Object? inputFormatters = null, + Object? alignmentOffset = freezed, + Object? expandedInsets = freezed, + Object? requestFocusOnTap = freezed, + Object? initialSelection = freezed, + Object? dropdownMenuEntries = null, + Object? closeBehavior = freezed, + }) { + return _then(_self.copyWith( + enabled: null == enabled + ? _self.enabled + : enabled // ignore: cast_nullable_to_non_nullable + as bool, + width: freezed == width + ? _self.width + : width // ignore: cast_nullable_to_non_nullable + as double?, + menuHeight: freezed == menuHeight + ? _self.menuHeight + : menuHeight // ignore: cast_nullable_to_non_nullable + as double?, + leadingIcon: freezed == leadingIcon + ? _self.leadingIcon + : leadingIcon // ignore: cast_nullable_to_non_nullable + as Map?, + trailingIcon: freezed == trailingIcon + ? _self.trailingIcon + : trailingIcon // ignore: cast_nullable_to_non_nullable + as Map?, + label: freezed == label + ? _self.label + : label // ignore: cast_nullable_to_non_nullable + as Map?, + hintText: freezed == hintText + ? _self.hintText + : hintText // ignore: cast_nullable_to_non_nullable + as String?, + helperText: freezed == helperText + ? _self.helperText + : helperText // ignore: cast_nullable_to_non_nullable + as String?, + errorText: freezed == errorText + ? _self.errorText + : errorText // ignore: cast_nullable_to_non_nullable + as String?, + selectedTrailingIcon: freezed == selectedTrailingIcon + ? _self.selectedTrailingIcon + : selectedTrailingIcon // ignore: cast_nullable_to_non_nullable + as Map?, + enableFilter: freezed == enableFilter + ? _self.enableFilter + : enableFilter // ignore: cast_nullable_to_non_nullable + as bool?, + enableSearch: freezed == enableSearch + ? _self.enableSearch + : enableSearch // ignore: cast_nullable_to_non_nullable + as bool?, + keyboardType: freezed == keyboardType + ? _self.keyboardType + : keyboardType // ignore: cast_nullable_to_non_nullable + as StacTextInputType?, + textStyle: freezed == textStyle + ? _self.textStyle + : textStyle // ignore: cast_nullable_to_non_nullable + as StacTextStyle?, + textAlign: null == textAlign + ? _self.textAlign + : textAlign // ignore: cast_nullable_to_non_nullable + as TextAlign, + inputDecorationTheme: freezed == inputDecorationTheme + ? _self.inputDecorationTheme + : inputDecorationTheme // ignore: cast_nullable_to_non_nullable + as StacInputDecorationTheme?, + inputFormatters: null == inputFormatters + ? _self.inputFormatters + : inputFormatters // ignore: cast_nullable_to_non_nullable + as List, + alignmentOffset: freezed == alignmentOffset + ? _self.alignmentOffset + : alignmentOffset // ignore: cast_nullable_to_non_nullable + as StacOffset?, + expandedInsets: freezed == expandedInsets + ? _self.expandedInsets + : expandedInsets // ignore: cast_nullable_to_non_nullable + as StacEdgeInsets?, + requestFocusOnTap: freezed == requestFocusOnTap + ? _self.requestFocusOnTap + : requestFocusOnTap // ignore: cast_nullable_to_non_nullable + as bool?, + initialSelection: freezed == initialSelection + ? _self.initialSelection + : initialSelection // ignore: cast_nullable_to_non_nullable + as dynamic, + dropdownMenuEntries: null == dropdownMenuEntries + ? _self.dropdownMenuEntries + : dropdownMenuEntries // ignore: cast_nullable_to_non_nullable + as List, + closeBehavior: freezed == closeBehavior + ? _self.closeBehavior + : closeBehavior // ignore: cast_nullable_to_non_nullable + as DropdownMenuCloseBehavior?, + )); + } + + /// Create a copy of StacDropdownMenu + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $StacTextStyleCopyWith<$Res>? get textStyle { + if (_self.textStyle == null) { + return null; + } + + return $StacTextStyleCopyWith<$Res>(_self.textStyle!, (value) { + return _then(_self.copyWith(textStyle: value)); + }); + } + + /// Create a copy of StacDropdownMenu + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $StacInputDecorationThemeCopyWith<$Res>? get inputDecorationTheme { + if (_self.inputDecorationTheme == null) { + return null; + } + + return $StacInputDecorationThemeCopyWith<$Res>(_self.inputDecorationTheme!, + (value) { + return _then(_self.copyWith(inputDecorationTheme: value)); + }); + } + + /// Create a copy of StacDropdownMenu + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $StacOffsetCopyWith<$Res>? get alignmentOffset { + if (_self.alignmentOffset == null) { + return null; + } + + return $StacOffsetCopyWith<$Res>(_self.alignmentOffset!, (value) { + return _then(_self.copyWith(alignmentOffset: value)); + }); + } + + /// Create a copy of StacDropdownMenu + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $StacEdgeInsetsCopyWith<$Res>? get expandedInsets { + if (_self.expandedInsets == null) { + return null; + } + + return $StacEdgeInsetsCopyWith<$Res>(_self.expandedInsets!, (value) { + return _then(_self.copyWith(expandedInsets: value)); + }); + } +} + +/// @nodoc +@JsonSerializable() +class _StacDropdownMenu implements StacDropdownMenu { + const _StacDropdownMenu( + {this.enabled = true, + this.width, + this.menuHeight, + final Map? leadingIcon, + final Map? trailingIcon, + final Map? label, + this.hintText, + this.helperText, + this.errorText, + final Map? selectedTrailingIcon, + this.enableFilter, + this.enableSearch, + this.keyboardType, + this.textStyle, + this.textAlign = TextAlign.start, + this.inputDecorationTheme, + final List inputFormatters = const [], + this.alignmentOffset, + this.expandedInsets, + this.requestFocusOnTap, + this.initialSelection, + final List dropdownMenuEntries = const [], + this.closeBehavior = DropdownMenuCloseBehavior.all}) + : _leadingIcon = leadingIcon, + _trailingIcon = trailingIcon, + _label = label, + _selectedTrailingIcon = selectedTrailingIcon, + _inputFormatters = inputFormatters, + _dropdownMenuEntries = dropdownMenuEntries; + factory _StacDropdownMenu.fromJson(Map json) => + _$StacDropdownMenuFromJson(json); + + @override + @JsonKey() + final bool enabled; + @override + final double? width; + @override + final double? menuHeight; + final Map? _leadingIcon; + @override + Map? get leadingIcon { + final value = _leadingIcon; + if (value == null) return null; + if (_leadingIcon is EqualUnmodifiableMapView) return _leadingIcon; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + final Map? _trailingIcon; + @override + Map? get trailingIcon { + final value = _trailingIcon; + if (value == null) return null; + if (_trailingIcon is EqualUnmodifiableMapView) return _trailingIcon; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + final Map? _label; + @override + Map? get label { + final value = _label; + if (value == null) return null; + if (_label is EqualUnmodifiableMapView) return _label; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + @override + final String? hintText; + @override + final String? helperText; + @override + final String? errorText; + final Map? _selectedTrailingIcon; + @override + Map? get selectedTrailingIcon { + final value = _selectedTrailingIcon; + if (value == null) return null; + if (_selectedTrailingIcon is EqualUnmodifiableMapView) + return _selectedTrailingIcon; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + @override + final bool? enableFilter; + @override + final bool? enableSearch; + @override + final StacTextInputType? keyboardType; + @override + final StacTextStyle? textStyle; + @override + @JsonKey() + final TextAlign textAlign; + @override + final StacInputDecorationTheme? inputDecorationTheme; + final List _inputFormatters; + @override + @JsonKey() + List get inputFormatters { + if (_inputFormatters is EqualUnmodifiableListView) return _inputFormatters; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_inputFormatters); + } + + @override + final StacOffset? alignmentOffset; + @override + final StacEdgeInsets? expandedInsets; + @override + final bool? requestFocusOnTap; +// TextEditingController? controller; + @override + final dynamic initialSelection; +// ValueChanged? onSelected; +// FocusNode? focusNode; + final List _dropdownMenuEntries; +// ValueChanged? onSelected; +// FocusNode? focusNode; + @override + @JsonKey() + List get dropdownMenuEntries { + if (_dropdownMenuEntries is EqualUnmodifiableListView) + return _dropdownMenuEntries; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_dropdownMenuEntries); + } + +// FilterCallback? filterCallback; +// SearchCallback? searchCallback, +// +// +// + @override + @JsonKey() + final DropdownMenuCloseBehavior? closeBehavior; + + /// Create a copy of StacDropdownMenu + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + _$StacDropdownMenuCopyWith<_StacDropdownMenu> get copyWith => + __$StacDropdownMenuCopyWithImpl<_StacDropdownMenu>(this, _$identity); + + @override + Map toJson() { + return _$StacDropdownMenuToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _StacDropdownMenu && + (identical(other.enabled, enabled) || other.enabled == enabled) && + (identical(other.width, width) || other.width == width) && + (identical(other.menuHeight, menuHeight) || + other.menuHeight == menuHeight) && + const DeepCollectionEquality() + .equals(other._leadingIcon, _leadingIcon) && + const DeepCollectionEquality() + .equals(other._trailingIcon, _trailingIcon) && + const DeepCollectionEquality().equals(other._label, _label) && + (identical(other.hintText, hintText) || + other.hintText == hintText) && + (identical(other.helperText, helperText) || + other.helperText == helperText) && + (identical(other.errorText, errorText) || + other.errorText == errorText) && + const DeepCollectionEquality() + .equals(other._selectedTrailingIcon, _selectedTrailingIcon) && + (identical(other.enableFilter, enableFilter) || + other.enableFilter == enableFilter) && + (identical(other.enableSearch, enableSearch) || + other.enableSearch == enableSearch) && + (identical(other.keyboardType, keyboardType) || + other.keyboardType == keyboardType) && + (identical(other.textStyle, textStyle) || + other.textStyle == textStyle) && + (identical(other.textAlign, textAlign) || + other.textAlign == textAlign) && + (identical(other.inputDecorationTheme, inputDecorationTheme) || + other.inputDecorationTheme == inputDecorationTheme) && + const DeepCollectionEquality() + .equals(other._inputFormatters, _inputFormatters) && + (identical(other.alignmentOffset, alignmentOffset) || + other.alignmentOffset == alignmentOffset) && + (identical(other.expandedInsets, expandedInsets) || + other.expandedInsets == expandedInsets) && + (identical(other.requestFocusOnTap, requestFocusOnTap) || + other.requestFocusOnTap == requestFocusOnTap) && + const DeepCollectionEquality() + .equals(other.initialSelection, initialSelection) && + const DeepCollectionEquality() + .equals(other._dropdownMenuEntries, _dropdownMenuEntries) && + (identical(other.closeBehavior, closeBehavior) || + other.closeBehavior == closeBehavior)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hashAll([ + runtimeType, + enabled, + width, + menuHeight, + const DeepCollectionEquality().hash(_leadingIcon), + const DeepCollectionEquality().hash(_trailingIcon), + const DeepCollectionEquality().hash(_label), + hintText, + helperText, + errorText, + const DeepCollectionEquality().hash(_selectedTrailingIcon), + enableFilter, + enableSearch, + keyboardType, + textStyle, + textAlign, + inputDecorationTheme, + const DeepCollectionEquality().hash(_inputFormatters), + alignmentOffset, + expandedInsets, + requestFocusOnTap, + const DeepCollectionEquality().hash(initialSelection), + const DeepCollectionEquality().hash(_dropdownMenuEntries), + closeBehavior + ]); + + @override + String toString() { + return 'StacDropdownMenu(enabled: $enabled, width: $width, menuHeight: $menuHeight, leadingIcon: $leadingIcon, trailingIcon: $trailingIcon, label: $label, hintText: $hintText, helperText: $helperText, errorText: $errorText, selectedTrailingIcon: $selectedTrailingIcon, enableFilter: $enableFilter, enableSearch: $enableSearch, keyboardType: $keyboardType, textStyle: $textStyle, textAlign: $textAlign, inputDecorationTheme: $inputDecorationTheme, inputFormatters: $inputFormatters, alignmentOffset: $alignmentOffset, expandedInsets: $expandedInsets, requestFocusOnTap: $requestFocusOnTap, initialSelection: $initialSelection, dropdownMenuEntries: $dropdownMenuEntries, closeBehavior: $closeBehavior)'; + } +} + +/// @nodoc +abstract mixin class _$StacDropdownMenuCopyWith<$Res> + implements $StacDropdownMenuCopyWith<$Res> { + factory _$StacDropdownMenuCopyWith( + _StacDropdownMenu value, $Res Function(_StacDropdownMenu) _then) = + __$StacDropdownMenuCopyWithImpl; + @override + @useResult + $Res call( + {bool enabled, + double? width, + double? menuHeight, + Map? leadingIcon, + Map? trailingIcon, + Map? label, + String? hintText, + String? helperText, + String? errorText, + Map? selectedTrailingIcon, + bool? enableFilter, + bool? enableSearch, + StacTextInputType? keyboardType, + StacTextStyle? textStyle, + TextAlign textAlign, + StacInputDecorationTheme? inputDecorationTheme, + List inputFormatters, + StacOffset? alignmentOffset, + StacEdgeInsets? expandedInsets, + bool? requestFocusOnTap, + dynamic initialSelection, + List dropdownMenuEntries, + DropdownMenuCloseBehavior? closeBehavior}); + + @override + $StacTextStyleCopyWith<$Res>? get textStyle; + @override + $StacInputDecorationThemeCopyWith<$Res>? get inputDecorationTheme; + @override + $StacOffsetCopyWith<$Res>? get alignmentOffset; + @override + $StacEdgeInsetsCopyWith<$Res>? get expandedInsets; +} + +/// @nodoc +class __$StacDropdownMenuCopyWithImpl<$Res> + implements _$StacDropdownMenuCopyWith<$Res> { + __$StacDropdownMenuCopyWithImpl(this._self, this._then); + + final _StacDropdownMenu _self; + final $Res Function(_StacDropdownMenu) _then; + + /// Create a copy of StacDropdownMenu + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? enabled = null, + Object? width = freezed, + Object? menuHeight = freezed, + Object? leadingIcon = freezed, + Object? trailingIcon = freezed, + Object? label = freezed, + Object? hintText = freezed, + Object? helperText = freezed, + Object? errorText = freezed, + Object? selectedTrailingIcon = freezed, + Object? enableFilter = freezed, + Object? enableSearch = freezed, + Object? keyboardType = freezed, + Object? textStyle = freezed, + Object? textAlign = null, + Object? inputDecorationTheme = freezed, + Object? inputFormatters = null, + Object? alignmentOffset = freezed, + Object? expandedInsets = freezed, + Object? requestFocusOnTap = freezed, + Object? initialSelection = freezed, + Object? dropdownMenuEntries = null, + Object? closeBehavior = freezed, + }) { + return _then(_StacDropdownMenu( + enabled: null == enabled + ? _self.enabled + : enabled // ignore: cast_nullable_to_non_nullable + as bool, + width: freezed == width + ? _self.width + : width // ignore: cast_nullable_to_non_nullable + as double?, + menuHeight: freezed == menuHeight + ? _self.menuHeight + : menuHeight // ignore: cast_nullable_to_non_nullable + as double?, + leadingIcon: freezed == leadingIcon + ? _self._leadingIcon + : leadingIcon // ignore: cast_nullable_to_non_nullable + as Map?, + trailingIcon: freezed == trailingIcon + ? _self._trailingIcon + : trailingIcon // ignore: cast_nullable_to_non_nullable + as Map?, + label: freezed == label + ? _self._label + : label // ignore: cast_nullable_to_non_nullable + as Map?, + hintText: freezed == hintText + ? _self.hintText + : hintText // ignore: cast_nullable_to_non_nullable + as String?, + helperText: freezed == helperText + ? _self.helperText + : helperText // ignore: cast_nullable_to_non_nullable + as String?, + errorText: freezed == errorText + ? _self.errorText + : errorText // ignore: cast_nullable_to_non_nullable + as String?, + selectedTrailingIcon: freezed == selectedTrailingIcon + ? _self._selectedTrailingIcon + : selectedTrailingIcon // ignore: cast_nullable_to_non_nullable + as Map?, + enableFilter: freezed == enableFilter + ? _self.enableFilter + : enableFilter // ignore: cast_nullable_to_non_nullable + as bool?, + enableSearch: freezed == enableSearch + ? _self.enableSearch + : enableSearch // ignore: cast_nullable_to_non_nullable + as bool?, + keyboardType: freezed == keyboardType + ? _self.keyboardType + : keyboardType // ignore: cast_nullable_to_non_nullable + as StacTextInputType?, + textStyle: freezed == textStyle + ? _self.textStyle + : textStyle // ignore: cast_nullable_to_non_nullable + as StacTextStyle?, + textAlign: null == textAlign + ? _self.textAlign + : textAlign // ignore: cast_nullable_to_non_nullable + as TextAlign, + inputDecorationTheme: freezed == inputDecorationTheme + ? _self.inputDecorationTheme + : inputDecorationTheme // ignore: cast_nullable_to_non_nullable + as StacInputDecorationTheme?, + inputFormatters: null == inputFormatters + ? _self._inputFormatters + : inputFormatters // ignore: cast_nullable_to_non_nullable + as List, + alignmentOffset: freezed == alignmentOffset + ? _self.alignmentOffset + : alignmentOffset // ignore: cast_nullable_to_non_nullable + as StacOffset?, + expandedInsets: freezed == expandedInsets + ? _self.expandedInsets + : expandedInsets // ignore: cast_nullable_to_non_nullable + as StacEdgeInsets?, + requestFocusOnTap: freezed == requestFocusOnTap + ? _self.requestFocusOnTap + : requestFocusOnTap // ignore: cast_nullable_to_non_nullable + as bool?, + initialSelection: freezed == initialSelection + ? _self.initialSelection + : initialSelection // ignore: cast_nullable_to_non_nullable + as dynamic, + dropdownMenuEntries: null == dropdownMenuEntries + ? _self._dropdownMenuEntries + : dropdownMenuEntries // ignore: cast_nullable_to_non_nullable + as List, + closeBehavior: freezed == closeBehavior + ? _self.closeBehavior + : closeBehavior // ignore: cast_nullable_to_non_nullable + as DropdownMenuCloseBehavior?, + )); + } + + /// Create a copy of StacDropdownMenu + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $StacTextStyleCopyWith<$Res>? get textStyle { + if (_self.textStyle == null) { + return null; + } + + return $StacTextStyleCopyWith<$Res>(_self.textStyle!, (value) { + return _then(_self.copyWith(textStyle: value)); + }); + } + + /// Create a copy of StacDropdownMenu + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $StacInputDecorationThemeCopyWith<$Res>? get inputDecorationTheme { + if (_self.inputDecorationTheme == null) { + return null; + } + + return $StacInputDecorationThemeCopyWith<$Res>(_self.inputDecorationTheme!, + (value) { + return _then(_self.copyWith(inputDecorationTheme: value)); + }); + } + + /// Create a copy of StacDropdownMenu + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $StacOffsetCopyWith<$Res>? get alignmentOffset { + if (_self.alignmentOffset == null) { + return null; + } + + return $StacOffsetCopyWith<$Res>(_self.alignmentOffset!, (value) { + return _then(_self.copyWith(alignmentOffset: value)); + }); + } + + /// Create a copy of StacDropdownMenu + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $StacEdgeInsetsCopyWith<$Res>? get expandedInsets { + if (_self.expandedInsets == null) { + return null; + } + + return $StacEdgeInsetsCopyWith<$Res>(_self.expandedInsets!, (value) { + return _then(_self.copyWith(expandedInsets: value)); + }); + } +} + +// dart format on diff --git a/packages/stac/lib/src/parsers/stac_dropdown_menu/stac_dropdown_menu.g.dart b/packages/stac/lib/src/parsers/stac_dropdown_menu/stac_dropdown_menu.g.dart new file mode 100644 index 00000000..3c41bb7e --- /dev/null +++ b/packages/stac/lib/src/parsers/stac_dropdown_menu/stac_dropdown_menu.g.dart @@ -0,0 +1,114 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'stac_dropdown_menu.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_StacDropdownMenu _$StacDropdownMenuFromJson(Map json) => + _StacDropdownMenu( + enabled: json['enabled'] as bool? ?? true, + width: (json['width'] as num?)?.toDouble(), + menuHeight: (json['menuHeight'] as num?)?.toDouble(), + leadingIcon: json['leadingIcon'] as Map?, + trailingIcon: json['trailingIcon'] as Map?, + label: json['label'] as Map?, + hintText: json['hintText'] as String?, + helperText: json['helperText'] as String?, + errorText: json['errorText'] as String?, + selectedTrailingIcon: + json['selectedTrailingIcon'] as Map?, + enableFilter: json['enableFilter'] as bool?, + enableSearch: json['enableSearch'] as bool?, + keyboardType: + $enumDecodeNullable(_$StacTextInputTypeEnumMap, json['keyboardType']), + textStyle: json['textStyle'] == null + ? null + : StacTextStyle.fromJson(json['textStyle']), + textAlign: $enumDecodeNullable(_$TextAlignEnumMap, json['textAlign']) ?? + TextAlign.start, + inputDecorationTheme: json['inputDecorationTheme'] == null + ? null + : StacInputDecorationTheme.fromJson( + json['inputDecorationTheme'] as Map), + inputFormatters: (json['inputFormatters'] as List?) + ?.map( + (e) => StacInputFormatter.fromJson(e as Map)) + .toList() ?? + const [], + alignmentOffset: json['alignmentOffset'] == null + ? null + : StacOffset.fromJson( + json['alignmentOffset'] as Map), + expandedInsets: json['expandedInsets'] == null + ? null + : StacEdgeInsets.fromJson(json['expandedInsets']), + requestFocusOnTap: json['requestFocusOnTap'] as bool?, + initialSelection: json['initialSelection'], + dropdownMenuEntries: (json['dropdownMenuEntries'] as List?) + ?.map((e) => + StacDropdownMenuEntry.fromJson(e as Map)) + .toList() ?? + const [], + closeBehavior: $enumDecodeNullable( + _$DropdownMenuCloseBehaviorEnumMap, json['closeBehavior']) ?? + DropdownMenuCloseBehavior.all, + ); + +Map _$StacDropdownMenuToJson(_StacDropdownMenu instance) => + { + 'enabled': instance.enabled, + 'width': instance.width, + 'menuHeight': instance.menuHeight, + 'leadingIcon': instance.leadingIcon, + 'trailingIcon': instance.trailingIcon, + 'label': instance.label, + 'hintText': instance.hintText, + 'helperText': instance.helperText, + 'errorText': instance.errorText, + 'selectedTrailingIcon': instance.selectedTrailingIcon, + 'enableFilter': instance.enableFilter, + 'enableSearch': instance.enableSearch, + 'keyboardType': _$StacTextInputTypeEnumMap[instance.keyboardType], + 'textStyle': instance.textStyle, + 'textAlign': _$TextAlignEnumMap[instance.textAlign]!, + 'inputDecorationTheme': instance.inputDecorationTheme, + 'inputFormatters': instance.inputFormatters, + 'alignmentOffset': instance.alignmentOffset, + 'expandedInsets': instance.expandedInsets, + 'requestFocusOnTap': instance.requestFocusOnTap, + 'initialSelection': instance.initialSelection, + 'dropdownMenuEntries': instance.dropdownMenuEntries, + 'closeBehavior': + _$DropdownMenuCloseBehaviorEnumMap[instance.closeBehavior], + }; + +const _$StacTextInputTypeEnumMap = { + StacTextInputType.text: 'text', + StacTextInputType.multiline: 'multiline', + StacTextInputType.number: 'number', + StacTextInputType.phone: 'phone', + StacTextInputType.datetime: 'datetime', + StacTextInputType.emailAddress: 'emailAddress', + StacTextInputType.url: 'url', + StacTextInputType.visiblePassword: 'visiblePassword', + StacTextInputType.name: 'name', + StacTextInputType.streetAddress: 'streetAddress', + StacTextInputType.none: 'none', +}; + +const _$TextAlignEnumMap = { + TextAlign.left: 'left', + TextAlign.right: 'right', + TextAlign.center: 'center', + TextAlign.justify: 'justify', + TextAlign.start: 'start', + TextAlign.end: 'end', +}; + +const _$DropdownMenuCloseBehaviorEnumMap = { + DropdownMenuCloseBehavior.all: 'all', + DropdownMenuCloseBehavior.self: 'self', + DropdownMenuCloseBehavior.none: 'none', +}; diff --git a/packages/stac/lib/src/parsers/stac_dropdown_menu/stac_dropdown_menu_parser.dart b/packages/stac/lib/src/parsers/stac_dropdown_menu/stac_dropdown_menu_parser.dart new file mode 100644 index 00000000..ea9e4660 --- /dev/null +++ b/packages/stac/lib/src/parsers/stac_dropdown_menu/stac_dropdown_menu_parser.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:stac/src/parsers/stac_dropdown_menu/stac_dropdown_menu.dart'; +import 'package:stac/src/parsers/stac_dropdown_menu_entry/stac_dropdown_menu_entry.dart'; +import 'package:stac/src/parsers/stac_input_decoration_theme/stac_input_decoration_theme.dart'; +import 'package:stac/src/parsers/stac_offset/stac_offset.dart'; +import 'package:stac/src/utils/widget_type.dart'; +import 'package:stac/stac.dart'; + +class StacDropdownMenuParser extends StacParser { + const StacDropdownMenuParser(); + + @override + String get type => WidgetType.dropdownMenu.name; + + @override + StacDropdownMenu getModel(Map json) => + StacDropdownMenu.fromJson(json); + + @override + Widget parse(BuildContext context, StacDropdownMenu model) { + return _DropDownMenuWidget(model: model); + } +} + +class _DropDownMenuWidget extends StatefulWidget { + const _DropDownMenuWidget({required this.model}); + + final StacDropdownMenu model; + + @override + State<_DropDownMenuWidget> createState() => _DropDownMenuWidgetState(); +} + +class _DropDownMenuWidgetState extends State<_DropDownMenuWidget> { + final TextEditingController _controller = TextEditingController(); + final _focusNode = FocusNode(); + late final StacDropdownMenu model; + + @override + void initState() { + model = widget.model; + super.initState(); + } + + @override + Widget build(BuildContext context) { + return DropdownMenu( + initialSelection: model.initialSelection, + focusNode: _focusNode, + controller: _controller, + dropdownMenuEntries: model.dropdownMenuEntries + .map((StacDropdownMenuEntry dropDownMenu) => + dropDownMenu.parse(context)!) + .toList(), + enabled: model.enabled, + width: model.width, + menuHeight: model.menuHeight, + leadingIcon: Stac.fromJson(model.leadingIcon, context), + trailingIcon: Stac.fromJson(model.trailingIcon, context), + label: Stac.fromJson(model.label, context), + hintText: model.hintText, + helperText: model.helperText, + errorText: model.errorText, + selectedTrailingIcon: Stac.fromJson(model.selectedTrailingIcon, context), + enableFilter: model.enableFilter ?? true, + enableSearch: model.enableSearch ?? true, + keyboardType: model.keyboardType?.value, + textStyle: model.textStyle?.parse(context), + textAlign: model.textAlign, + inputDecorationTheme: model.inputDecorationTheme.parse(context), + requestFocusOnTap: model.requestFocusOnTap, + expandedInsets: model.expandedInsets.parse, + alignmentOffset: model.alignmentOffset?.parse, + inputFormatters: model.inputFormatters + .map((StacInputFormatter formatter) => + formatter.type.format(formatter.rule ?? "")) + .toList(), + ); + } +} diff --git a/packages/stac/lib/src/parsers/stac_dropdown_menu_entry/stac_dropdown_menu_entry.dart b/packages/stac/lib/src/parsers/stac_dropdown_menu_entry/stac_dropdown_menu_entry.dart new file mode 100644 index 00000000..1aa97cbe --- /dev/null +++ b/packages/stac/lib/src/parsers/stac_dropdown_menu_entry/stac_dropdown_menu_entry.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:stac/src/framework/framework.dart' show Stac; +import 'package:stac/src/parsers/parsers.dart'; + +part 'stac_dropdown_menu_entry.freezed.dart'; +part 'stac_dropdown_menu_entry.g.dart'; + +@freezed +abstract class StacDropdownMenuEntry with _$StacDropdownMenuEntry { + const factory StacDropdownMenuEntry({ + dynamic value, + @Default("") String label, + Map? labelWidget, + Map? leadingIcon, + Map? trailingIcon, + @Default(true) bool enabled, + StacButtonStyle? style, + }) = _StacBDropdownMenuEntry; + + factory StacDropdownMenuEntry.fromJson(Map json) => + _$StacDropdownMenuEntryFromJson(json); +} + +extension StacDropdownMenuEntryParser on StacDropdownMenuEntry? { + DropdownMenuEntry? parse(BuildContext context) { + return DropdownMenuEntry( + value: this?.value, + label: this!.label, + labelWidget: Stac.fromJson(this?.labelWidget, context), + leadingIcon: Stac.fromJson(this?.leadingIcon, context), + enabled: this?.enabled ?? true, + style: this?.style?.parseText(context), + ); + } +} diff --git a/packages/stac/lib/src/parsers/stac_dropdown_menu_entry/stac_dropdown_menu_entry.freezed.dart b/packages/stac/lib/src/parsers/stac_dropdown_menu_entry/stac_dropdown_menu_entry.freezed.dart new file mode 100644 index 00000000..1608a00d --- /dev/null +++ b/packages/stac/lib/src/parsers/stac_dropdown_menu_entry/stac_dropdown_menu_entry.freezed.dart @@ -0,0 +1,360 @@ +// dart format width=80 +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'stac_dropdown_menu_entry.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +StacDropdownMenuEntry _$StacDropdownMenuEntryFromJson( + Map json) { + return _StacBDropdownMenuEntry.fromJson(json); +} + +/// @nodoc +mixin _$StacDropdownMenuEntry { + dynamic get value; + String get label; + Map? get labelWidget; + Map? get leadingIcon; + Map? get trailingIcon; + bool get enabled; + StacButtonStyle? get style; + + /// Create a copy of StacDropdownMenuEntry + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $StacDropdownMenuEntryCopyWith get copyWith => + _$StacDropdownMenuEntryCopyWithImpl( + this as StacDropdownMenuEntry, _$identity); + + /// Serializes this StacDropdownMenuEntry to a JSON map. + Map toJson(); + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is StacDropdownMenuEntry && + const DeepCollectionEquality().equals(other.value, value) && + (identical(other.label, label) || other.label == label) && + const DeepCollectionEquality() + .equals(other.labelWidget, labelWidget) && + const DeepCollectionEquality() + .equals(other.leadingIcon, leadingIcon) && + const DeepCollectionEquality() + .equals(other.trailingIcon, trailingIcon) && + (identical(other.enabled, enabled) || other.enabled == enabled) && + (identical(other.style, style) || other.style == style)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(value), + label, + const DeepCollectionEquality().hash(labelWidget), + const DeepCollectionEquality().hash(leadingIcon), + const DeepCollectionEquality().hash(trailingIcon), + enabled, + style); + + @override + String toString() { + return 'StacDropdownMenuEntry(value: $value, label: $label, labelWidget: $labelWidget, leadingIcon: $leadingIcon, trailingIcon: $trailingIcon, enabled: $enabled, style: $style)'; + } +} + +/// @nodoc +abstract mixin class $StacDropdownMenuEntryCopyWith<$Res> { + factory $StacDropdownMenuEntryCopyWith(StacDropdownMenuEntry value, + $Res Function(StacDropdownMenuEntry) _then) = + _$StacDropdownMenuEntryCopyWithImpl; + @useResult + $Res call( + {dynamic value, + String label, + Map? labelWidget, + Map? leadingIcon, + Map? trailingIcon, + bool enabled, + StacButtonStyle? style}); + + $StacButtonStyleCopyWith<$Res>? get style; +} + +/// @nodoc +class _$StacDropdownMenuEntryCopyWithImpl<$Res> + implements $StacDropdownMenuEntryCopyWith<$Res> { + _$StacDropdownMenuEntryCopyWithImpl(this._self, this._then); + + final StacDropdownMenuEntry _self; + final $Res Function(StacDropdownMenuEntry) _then; + + /// Create a copy of StacDropdownMenuEntry + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? value = freezed, + Object? label = null, + Object? labelWidget = freezed, + Object? leadingIcon = freezed, + Object? trailingIcon = freezed, + Object? enabled = null, + Object? style = freezed, + }) { + return _then(_self.copyWith( + value: freezed == value + ? _self.value + : value // ignore: cast_nullable_to_non_nullable + as dynamic, + label: null == label + ? _self.label + : label // ignore: cast_nullable_to_non_nullable + as String, + labelWidget: freezed == labelWidget + ? _self.labelWidget + : labelWidget // ignore: cast_nullable_to_non_nullable + as Map?, + leadingIcon: freezed == leadingIcon + ? _self.leadingIcon + : leadingIcon // ignore: cast_nullable_to_non_nullable + as Map?, + trailingIcon: freezed == trailingIcon + ? _self.trailingIcon + : trailingIcon // ignore: cast_nullable_to_non_nullable + as Map?, + enabled: null == enabled + ? _self.enabled + : enabled // ignore: cast_nullable_to_non_nullable + as bool, + style: freezed == style + ? _self.style + : style // ignore: cast_nullable_to_non_nullable + as StacButtonStyle?, + )); + } + + /// Create a copy of StacDropdownMenuEntry + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $StacButtonStyleCopyWith<$Res>? get style { + if (_self.style == null) { + return null; + } + + return $StacButtonStyleCopyWith<$Res>(_self.style!, (value) { + return _then(_self.copyWith(style: value)); + }); + } +} + +/// @nodoc +@JsonSerializable() +class _StacBDropdownMenuEntry implements StacDropdownMenuEntry { + const _StacBDropdownMenuEntry( + {this.value, + this.label = "", + final Map? labelWidget, + final Map? leadingIcon, + final Map? trailingIcon, + this.enabled = true, + this.style}) + : _labelWidget = labelWidget, + _leadingIcon = leadingIcon, + _trailingIcon = trailingIcon; + factory _StacBDropdownMenuEntry.fromJson(Map json) => + _$StacBDropdownMenuEntryFromJson(json); + + @override + final dynamic value; + @override + @JsonKey() + final String label; + final Map? _labelWidget; + @override + Map? get labelWidget { + final value = _labelWidget; + if (value == null) return null; + if (_labelWidget is EqualUnmodifiableMapView) return _labelWidget; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + final Map? _leadingIcon; + @override + Map? get leadingIcon { + final value = _leadingIcon; + if (value == null) return null; + if (_leadingIcon is EqualUnmodifiableMapView) return _leadingIcon; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + final Map? _trailingIcon; + @override + Map? get trailingIcon { + final value = _trailingIcon; + if (value == null) return null; + if (_trailingIcon is EqualUnmodifiableMapView) return _trailingIcon; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + @override + @JsonKey() + final bool enabled; + @override + final StacButtonStyle? style; + + /// Create a copy of StacDropdownMenuEntry + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + _$StacBDropdownMenuEntryCopyWith<_StacBDropdownMenuEntry> get copyWith => + __$StacBDropdownMenuEntryCopyWithImpl<_StacBDropdownMenuEntry>( + this, _$identity); + + @override + Map toJson() { + return _$StacBDropdownMenuEntryToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _StacBDropdownMenuEntry && + const DeepCollectionEquality().equals(other.value, value) && + (identical(other.label, label) || other.label == label) && + const DeepCollectionEquality() + .equals(other._labelWidget, _labelWidget) && + const DeepCollectionEquality() + .equals(other._leadingIcon, _leadingIcon) && + const DeepCollectionEquality() + .equals(other._trailingIcon, _trailingIcon) && + (identical(other.enabled, enabled) || other.enabled == enabled) && + (identical(other.style, style) || other.style == style)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(value), + label, + const DeepCollectionEquality().hash(_labelWidget), + const DeepCollectionEquality().hash(_leadingIcon), + const DeepCollectionEquality().hash(_trailingIcon), + enabled, + style); + + @override + String toString() { + return 'StacDropdownMenuEntry(value: $value, label: $label, labelWidget: $labelWidget, leadingIcon: $leadingIcon, trailingIcon: $trailingIcon, enabled: $enabled, style: $style)'; + } +} + +/// @nodoc +abstract mixin class _$StacBDropdownMenuEntryCopyWith<$Res> + implements $StacDropdownMenuEntryCopyWith<$Res> { + factory _$StacBDropdownMenuEntryCopyWith(_StacBDropdownMenuEntry value, + $Res Function(_StacBDropdownMenuEntry) _then) = + __$StacBDropdownMenuEntryCopyWithImpl; + @override + @useResult + $Res call( + {dynamic value, + String label, + Map? labelWidget, + Map? leadingIcon, + Map? trailingIcon, + bool enabled, + StacButtonStyle? style}); + + @override + $StacButtonStyleCopyWith<$Res>? get style; +} + +/// @nodoc +class __$StacBDropdownMenuEntryCopyWithImpl<$Res> + implements _$StacBDropdownMenuEntryCopyWith<$Res> { + __$StacBDropdownMenuEntryCopyWithImpl(this._self, this._then); + + final _StacBDropdownMenuEntry _self; + final $Res Function(_StacBDropdownMenuEntry) _then; + + /// Create a copy of StacDropdownMenuEntry + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? value = freezed, + Object? label = null, + Object? labelWidget = freezed, + Object? leadingIcon = freezed, + Object? trailingIcon = freezed, + Object? enabled = null, + Object? style = freezed, + }) { + return _then(_StacBDropdownMenuEntry( + value: freezed == value + ? _self.value + : value // ignore: cast_nullable_to_non_nullable + as dynamic, + label: null == label + ? _self.label + : label // ignore: cast_nullable_to_non_nullable + as String, + labelWidget: freezed == labelWidget + ? _self._labelWidget + : labelWidget // ignore: cast_nullable_to_non_nullable + as Map?, + leadingIcon: freezed == leadingIcon + ? _self._leadingIcon + : leadingIcon // ignore: cast_nullable_to_non_nullable + as Map?, + trailingIcon: freezed == trailingIcon + ? _self._trailingIcon + : trailingIcon // ignore: cast_nullable_to_non_nullable + as Map?, + enabled: null == enabled + ? _self.enabled + : enabled // ignore: cast_nullable_to_non_nullable + as bool, + style: freezed == style + ? _self.style + : style // ignore: cast_nullable_to_non_nullable + as StacButtonStyle?, + )); + } + + /// Create a copy of StacDropdownMenuEntry + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $StacButtonStyleCopyWith<$Res>? get style { + if (_self.style == null) { + return null; + } + + return $StacButtonStyleCopyWith<$Res>(_self.style!, (value) { + return _then(_self.copyWith(style: value)); + }); + } +} + +// dart format on diff --git a/packages/stac/lib/src/parsers/stac_dropdown_menu_entry/stac_dropdown_menu_entry.g.dart b/packages/stac/lib/src/parsers/stac_dropdown_menu_entry/stac_dropdown_menu_entry.g.dart new file mode 100644 index 00000000..fd725c87 --- /dev/null +++ b/packages/stac/lib/src/parsers/stac_dropdown_menu_entry/stac_dropdown_menu_entry.g.dart @@ -0,0 +1,33 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'stac_dropdown_menu_entry.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_StacBDropdownMenuEntry _$StacBDropdownMenuEntryFromJson( + Map json) => + _StacBDropdownMenuEntry( + value: json['value'], + label: json['label'] as String? ?? "", + labelWidget: json['labelWidget'] as Map?, + leadingIcon: json['leadingIcon'] as Map?, + trailingIcon: json['trailingIcon'] as Map?, + enabled: json['enabled'] as bool? ?? true, + style: json['style'] == null + ? null + : StacButtonStyle.fromJson(json['style'] as Map), + ); + +Map _$StacBDropdownMenuEntryToJson( + _StacBDropdownMenuEntry instance) => + { + 'value': instance.value, + 'label': instance.label, + 'labelWidget': instance.labelWidget, + 'leadingIcon': instance.leadingIcon, + 'trailingIcon': instance.trailingIcon, + 'enabled': instance.enabled, + 'style': instance.style, + }; diff --git a/packages/stac/lib/src/utils/widget_type.dart b/packages/stac/lib/src/utils/widget_type.dart index e38c0bc3..1f2fef18 100644 --- a/packages/stac/lib/src/utils/widget_type.dart +++ b/packages/stac/lib/src/utils/widget_type.dart @@ -16,6 +16,7 @@ enum WidgetType { coloredBox, column, container, + dropdownMenu, customScrollView, defaultBottomNavigationController, defaultTabController, diff --git a/website/docs/widgets/dropdown_menu.md b/website/docs/widgets/dropdown_menu.md new file mode 100644 index 00000000..b00088cd --- /dev/null +++ b/website/docs/widgets/dropdown_menu.md @@ -0,0 +1,82 @@ +# DropdownMenu + +The Stac DropdownMenu allows you to build a Flutter DropdownMenu widget using JSON. +To know more about the DropdownMenu widget in Flutter, refer to +the [official documentation](https://api.flutter.dev/flutter/material/DropdownMenu-class.html). + +## Properties + +| Property | Type | Description | +|----------------------|---------------------------------|-----------------------------------------------------------| +| dropdownMenuEntries | `List` | The entries to display in the dropdown menu. | +| initialSelection | `dynamic` | The initial selection value. | +| enabled | `bool` | Whether the dropdown menu is enabled. Defaults to `true`. | +| label | `Map?` | The label to display for the dropdown menu. | +| leadingIcon | `Map?` | The icon to display at the start of the dropdown menu. | +| trailingIcon | `Map?` | The icon to display at the end of the dropdown menu. | +| hintText | `String?` | The hint text to display when no selection is made. | +| errorText | `String?` | The error text to display when there is an error. | +| width | `double?` | The width of the dropdown menu. | +| menuHeight | `double?` | The height of the dropdown menu. | +| inputDecorationTheme | `StacInputDecorationTheme?` | The theme to use for the input decoration. | +| textStyle | `StacTextStyle?` | The text style to use for the dropdown menu. | +| enableFilter | `bool` | Whether to enable filtering. Defaults to `true`. | +| enableSearch | `bool` | Whether to enable search. Defaults to `true`. | +| requestFocusOnTap | `bool` | Whether to request focus on tap. Defaults to `true`. | + +# DropdownMenuEntry + +The Stac DropdownMenuEntry allows you to build a Flutter DropdownMenuEntry widget using JSON. +To know more about the DropdownMenuEntry widget in Flutter, refer to +the [official documentation](https://api.flutter.dev/flutter/material/DropdownMenuEntry-class.html). + +## Properties + +| Property | Type | Description | +|--------------|-------------------------|----------------------------------------------------| +| value | `dynamic` | The value associated with this entry. | +| label | `String` | The label to display for this entry. | +| enabled | `bool` | Whether this entry is enabled. Defaults to `true`. | +| leadingIcon | `Map?` | The icon to display at the start of this entry. | +| trailingIcon | `Map?` | The icon to display at the end of this entry. | +| style | `StacButtonStyle?` | The style to use for this entry. | + +## Example JSON + +```json +{ + "type": "dropdownMenu", + "label": { + "type": "text", + "data": "Select an option" + }, + "hintText": "Please select", + "width": 200, + "dropdownMenuEntries": [ + { + "value": "option1", + "label": "Option 1", + "leadingIcon": { + "type": "icon", + "iconData": "home" + } + }, + { + "value": "option2", + "label": "Option 2", + "leadingIcon": { + "type": "icon", + "iconData": "settings" + } + }, + { + "value": "option3", + "label": "Option 3", + "leadingIcon": { + "type": "icon", + "iconData": "favorite" + } + } + ] +} +``` \ No newline at end of file