diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index db8a9b2..43d42eb 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"path_provider_android","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_android-2.2.4\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2024-05-14 12:46:40.683553","version":"3.19.0"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"path_provider_android","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_android-2.2.4\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\Micazi\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2024-05-14 14:05:55.671847","version":"3.19.0"} \ No newline at end of file diff --git a/README.md b/README.md index baf5aad..1a9c701 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,13 @@ Developed, Maintained, and is property of Michael W. Aziz (Micazi) - VSB,HSB ☑️ - Flexer ☑️ - Divider ☑️ +- Widgets + - Image ☑️ + - Scaffold ☑️ + - Blur ☑️ +- Selectors + - Radio + - Chip - Buttons - Fields -- Selectors - Toggles -- Widgets - - Image - - Scaffold - - Blur diff --git a/analysis_options.yaml b/analysis_options.yaml index f9b3034..7c2f3d3 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1 +1,9 @@ include: package:flutter_lints/flutter.yaml +linter: + rules: + - prefer_relative_imports + - close_sinks + - avoid_empty_else + - file_names + - prefer_const_constructors + - no_leading_underscores_for_local_identifiers diff --git a/lib/src/Selectors/selectors.astromic.dart b/lib/src/Selectors/selectors.astromic.dart new file mode 100644 index 0000000..76a5134 --- /dev/null +++ b/lib/src/Selectors/selectors.astromic.dart @@ -0,0 +1,31 @@ +//s2 Core Packages Imports + +import 'package:flutter/widgets.dart'; + +class AstromicSelectors { + //S1 -- Radio + static Widget radio({ + T? initialSelectedValue, + Function(T selectedItem)? onChanged, + // + AstromicSelectorConfiguration? configurations, + // + double? itemSpacing = 4, + // + required Widget Function(AstromicRadioSelectorItem item, VoidCallback? onTap, bool isSelected) itemBuilder, + Widget Function(AstromicRadioSelectorItem item)? disabledItemBuilder, + required List> items, + }) => + astromicRadioSelector( + initialSelectedValue: initialSelectedValue, + onChanged: onChanged, + // + configurations: configurations, + // + itemSpacing: itemSpacing, + // + itemBuilder: itemBuilder, + disabledItemBuilder: disabledItemBuilder, + items: items, + ); +} diff --git a/lib/src/Selectors/src/configuration.dart b/lib/src/Selectors/src/configuration.dart new file mode 100644 index 0000000..8d6e9ae --- /dev/null +++ b/lib/src/Selectors/src/configuration.dart @@ -0,0 +1,45 @@ +import 'package:flutter/widgets.dart'; + +class AstromicSelectorConfiguration { + //s1 Shared + final Axis axis; + final bool isNullable; + //s1 Chip Specific + final bool isConsequent; + final bool withClearButton; + final int maxSelectedItems; + final int crossAxisCount; + //s1 Radio Specific + final bool withExpandedSpace; + const AstromicSelectorConfiguration({ + this.axis = Axis.horizontal, + this.isNullable = true, + // + this.isConsequent = false, + this.withClearButton = false, + this.maxSelectedItems = 10000, + this.crossAxisCount = 3, + // + this.withExpandedSpace = false, + }); + + AstromicSelectorConfiguration copyWith({ + Axis? axis, + bool? isNullable, + bool? isConsequent, + bool? withClearButton, + int? maxSelectedItems, + int? crossAxisCount, + bool? withExpandedSpace, + }) { + return AstromicSelectorConfiguration( + axis: axis ?? this.axis, + isNullable: isNullable ?? this.isNullable, + isConsequent: isConsequent ?? this.isConsequent, + withClearButton: withClearButton ?? this.withClearButton, + maxSelectedItems: maxSelectedItems ?? this.maxSelectedItems, + crossAxisCount: crossAxisCount ?? this.crossAxisCount, + withExpandedSpace: withExpandedSpace ?? this.withExpandedSpace, + ); + } +} diff --git a/lib/src/Selectors/src/radio.selector.dart b/lib/src/Selectors/src/radio.selector.dart new file mode 100644 index 0000000..30399b2 --- /dev/null +++ b/lib/src/Selectors/src/radio.selector.dart @@ -0,0 +1,207 @@ +//SECTION - Imports +// +//s1 PACKAGES +//--------------- +//s2 CORE +import 'package:flutter/widgets.dart'; +//s2 3RD-PARTY +// +//s1 DEPENDENCIES +//--------------- +//s2 SERVICES +//s2 MODELS +import 'configuration.dart'; +//s2 MISC +//!SECTION - Imports +// +//SECTION - Exports +//!SECTION - Exports +// + +// +class AstromicRadioSelector extends StatefulWidget { + //SECTION - Widget Arguments + //s1 -- Functionality + final T? initialSelectedValue; + final Function(T selectedItem)? onChanged; + //s1 -- Configuration + final AstromicSelectorConfiguration? configurations; + //s1 -- Style + final double? itemSpacing; + //s1 -- Content + final List> items; + // + final Widget Function(AstromicRadioSelectorItem item, VoidCallback? onTap, bool isSelected) itemBuilder; + final Widget Function(AstromicRadioSelectorItem item)? disabledItemBuilder; + //!SECTION + // + AstromicRadioSelector({ + Key? key, + //s1 -- Functionality + this.initialSelectedValue, + required this.items, + this.onChanged, + //s1 -- Configuration + this.configurations = const AstromicSelectorConfiguration(), + //s1 -- Style + this.itemSpacing = 8, + //s1 -- Content + required this.itemBuilder, + this.disabledItemBuilder, + }) : assert(configurations!.isNullable || initialSelectedValue != null, 'You need to supply an initial value if not nullable!'), + assert( + configurations!.isNullable || + (items + .map( + (e) => e.value, + ) + .toList() + .contains(initialSelectedValue)), + "Initial value is not present in the items!", + ), + super( + key: key, + ); + + @override + State> createState() => _AstromicRadioSelectorState(); +} + +class _AstromicRadioSelectorState extends State> { + // + //SECTION - State Variables + //s1 --Controllers + //s1 --Controllers + // + //s1 --State + late T? selectedItem; + //s1 --State + // + //s1 --Constants + //s1 --Constants + //!SECTION + + @override + void initState() { + super.initState(); + // + //SECTION - State Variables initializations & Listeners + //s1 --Controllers & Listeners + //s1 --Controllers & Listeners + // + //s1 --State + selectedItem = widget.initialSelectedValue; + //s1 --State + // + //s1 --Late & Async Initializers + //s1 --Late & Async Initializers + //!SECTION + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + // + //SECTION - State Variables initializations & Listeners + //s1 --State + //s1 --State + //!SECTION + } + //SECTION - Stateless functions + //!SECTION + + //SECTION - Action Callbacks + _onTap(T value) { + setState(() { + selectedItem = value; + }); + if (widget.onChanged != null) widget.onChanged!(value); + } + //!SECTION + + @override + Widget build(BuildContext context) { + //SECTION - Build Setup + //s1 -Values + //double w = MediaQuery.of(context).size.width; + //double h = MediaQuery.of(context).size.height; + //s1 -Values + // + //s1 -Widgets + List baseChildren = widget.items.map((currentItem) { + bool isSelected = currentItem.value == selectedItem; + // + return !currentItem.enabled! && widget.disabledItemBuilder != null + ? widget.configurations!.withExpandedSpace + ? Expanded(child: widget.disabledItemBuilder!(currentItem)) + : widget.disabledItemBuilder!(currentItem) + : widget.configurations!.withExpandedSpace + ? Expanded(child: widget.itemBuilder(currentItem, currentItem.enabled! ? () => _onTap(currentItem.value) : null, isSelected)) + : widget.itemBuilder(currentItem, currentItem.enabled! ? () => _onTap(currentItem.value) : null, isSelected); + }).toList(); + //s1 -Widgets + //!SECTION + + //SECTION - Build Return + return widget.configurations!.withExpandedSpace + ? widget.configurations!.axis == Axis.horizontal + ? separatedRow( + baseChildren, + AstromicSpacing.hsb(widget.itemSpacing!), + ) + : separatedColumn( + baseChildren, + AstromicSpacing.vsb(widget.itemSpacing!), + ) + : Wrap( + alignment: WrapAlignment.center, + runAlignment: WrapAlignment.center, + crossAxisAlignment: WrapCrossAlignment.center, + direction: widget.configurations!.axis, + spacing: widget.itemSpacing!, + children: baseChildren, + ); + //!SECTION + } + + @override + void dispose() { + //SECTION - Disposable variables + //!SECTION + super.dispose(); + } +} + +Widget separatedRow(List children, Widget separator) { + List finalChildren = []; + for (var e in children) { + if (children.indexOf(e) != children.length - 1) { + finalChildren.addAll([e, separator]); + } else { + finalChildren.add(e); + } + } + return Row( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: finalChildren, + ); +} + +Widget separatedColumn(List children, Widget separator) { + List finalChildren = []; + for (var e in children) { + if (children.indexOf(e) != children.length - 1) { + finalChildren.addAll([e, separator]); + } else { + finalChildren.add(e); + } + } + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: finalChildren, + ); +} diff --git a/lib/src/Widgets/widgets.astromic.dart b/lib/src/Widgets/widgets.astromic.dart index a0a716e..eb0f5ac 100644 --- a/lib/src/Widgets/widgets.astromic.dart +++ b/lib/src/Widgets/widgets.astromic.dart @@ -1,7 +1,7 @@ import 'dart:typed_data'; //s2 Core Packages Imports -import 'package:astromic_mobile_elements/src/Widgets/src/blur.widget.dart'; -import 'package:astromic_mobile_elements/src/Widgets/src/scaffold.widget.dart'; +import 'src/blur.widget.dart'; +import 'src/scaffold.widget.dart'; import 'src/image.widget.dart'; import 'package:flutter/material.dart';