diff --git a/packages/chicken/lib/presentation/widget/sdui/form/sdui_form_widget.dart b/packages/chicken/lib/presentation/widget/sdui/form/sdui_form_widget.dart index 7f4786d..b6da26c 100644 --- a/packages/chicken/lib/presentation/widget/sdui/form/sdui_form_widget.dart +++ b/packages/chicken/lib/presentation/widget/sdui/form/sdui_form_widget.dart @@ -30,6 +30,101 @@ class _StepperInfo { }); } +// Helper widget that adds spacing only if previous widget is visible +class _SpacingWidget extends StatelessWidget { + final double spacing; + final String? previousVisibleCondition; + final RxMap? state; + + const _SpacingWidget({ + required this.spacing, + required this.previousVisibleCondition, + required this.state, + }); + + @override + Widget build(BuildContext context) { + // If previous widget has no visible condition, it's always visible + if (previousVisibleCondition == null || previousVisibleCondition!.isEmpty) { + return SizedBox(height: spacing); + } + + // Use Obx to reactively check if previous widget is visible + return Obx(() { + final isPreviousVisible = _evaluateVisibleConditionStatic( + previousVisibleCondition!, + state, + ); + + if (isPreviousVisible) { + return SizedBox(height: spacing); + } else { + return const SizedBox.shrink(); + } + }); + } + + // Static version of _evaluateVisibleCondition for use in helper widget + bool _evaluateVisibleConditionStatic( + String condition, + RxMap? state, + ) { + if (state == null) { + if (condition.contains('activeStepperIndex == 0')) { + return true; + } + return false; + } + + try { + // Simple condition evaluation + // Supports: variable == value + + if (condition.contains(' == ')) { + final parts = condition.split(' == '); + if (parts.length == 2) { + final variable = parts[0].trim(); + var value = parts[1].trim(); + + // Remove quotes if present + if ((value.startsWith("'") && value.endsWith("'")) || + (value.startsWith('"') && value.endsWith('"'))) { + value = value.substring(1, value.length - 1); + } + + final stateValue = state[variable]; + if (stateValue == null) { + // If variable doesn't exist in state, default to showing first step (0) + if (variable == 'activeStepperIndex' && value == '0') { + return true; + } + return false; + } + + // Handle int comparison + final intValue = int.tryParse(value); + if (intValue != null) { + if (stateValue is int) { + return stateValue == intValue; + } + if (stateValue is num) { + return stateValue.toInt() == intValue; + } + } + + // Handle string comparison + return stateValue.toString() == value; + } + } + + // If condition format is not recognized, return false + return false; + } catch (e) { + return false; + } + } +} + class SDUIFormWidget extends StatelessWidget { final SDUIWidgetModel model; final Map? controllers; @@ -187,15 +282,25 @@ class SDUIFormWidget extends StatelessWidget { if (visibleCondition.contains('activeStepperIndex == 0')) { return builder(); } - return const SizedBox.shrink(); + return Visibility( + visible: false, + maintainSize: false, + maintainState: false, + maintainAnimation: false, + child: builder(), + ); } // Use Obx for reactive updates return Obx(() { - if (!_evaluateVisibleCondition(visibleCondition)) { - return const SizedBox.shrink(); - } - return builder(); + final isVisible = _evaluateVisibleCondition(visibleCondition); + return Visibility( + visible: isVisible, + maintainSize: false, + maintainState: false, + maintainAnimation: false, + child: builder(), + ); }); } @@ -316,7 +421,6 @@ class SDUIFormWidget extends StatelessWidget { double paddingVertical, ) { if (children.isEmpty) { - iLog('Column has no children'); return const SizedBox.shrink(); } @@ -328,31 +432,84 @@ class SDUIFormWidget extends StatelessWidget { crossAxisAlignment, ); - final builtChildren = children.map((child) { + // Build all children first and extract their visible conditions + final builtChildren = []; + final visibleConditions = []; + + for (final child in children) { try { - return _buildWidget(child); + // Extract visible_condition from child model + final visibleCondition = child.maybeWhen( + column: + ( + children, + spacing, + mainAxisSize, + crossAxisAlignment, + paddingHorizontal, + paddingVertical, + visible, + visibleCondition, + ) => visibleCondition, + row: + ( + children, + spacing, + mainAxisAlignment, + visible, + visibleCondition, + ) => visibleCondition, + cardLabelItem: (data, child, children, visible, visibleCondition) => + visibleCondition, + stepper: (data, children, visible, visibleCondition) => + visibleCondition, + textFormField: (data, visible, visibleCondition) => + visibleCondition, + chipSelection: (data, visible, visibleCondition) => + visibleCondition, + dropdown: (data, visible, visibleCondition) => visibleCondition, + imagePicker: (data, visible, visibleCondition) => visibleCondition, + pageView: (data, children, visible, visibleCondition) => + visibleCondition, + sizedBox: (width, height, visible, visibleCondition) => + visibleCondition, + orElse: () => null, + ); + + visibleConditions.add(visibleCondition); + builtChildren.add(_buildWidget(child)); } catch (e) { iLog('Error building column child: $e'); - return Container( - padding: EdgeInsets.all(8), - color: Colors.yellow.withAlpha(10), - child: Text('Child Error'), + visibleConditions.add(null); + builtChildren.add( + Container( + padding: EdgeInsets.all(8), + color: Colors.yellow.withAlpha(10), + child: Text('Child Error'), + ), ); } - }).toList(); + } // Add spacing between children - final columnChildren = spacing > 0 && builtChildren.length > 1 - ? [] - : builtChildren; + // Wrap each child (except first) with spacing that only shows if previous child is visible + final columnChildren = []; - if (spacing > 0 && builtChildren.length > 1) { - for (int i = 0; i < builtChildren.length; i++) { - columnChildren.add(builtChildren[i]); - if (i < builtChildren.length - 1) { - columnChildren.add(SizedBox(height: spacing)); - } + for (int i = 0; i < builtChildren.length; i++) { + final widget = builtChildren[i]; + + if (i > 0 && spacing > 0) { + // Add spacing that will be removed if previous widget is invisible + // Use the visible_condition of the previous widget + columnChildren.add( + _SpacingWidget( + spacing: spacing, + previousVisibleCondition: visibleConditions[i - 1], + state: state, + ), + ); } + columnChildren.add(widget); } final column = Column( @@ -849,6 +1006,8 @@ class SDUIFormWidget extends StatelessWidget { 'sdui_form_stepper_${stepperInfo.stepperData.key ?? 'default'}'; SDUIFormWidgetController formController; + fLog('mj ==>build With Stepper Layout'); + try { formController = Get.find(tag: controllerTag); } catch (_) { @@ -931,6 +1090,7 @@ class SDUIFormWidget extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, + spacing: 30.h, children: contentWidgets, ), ),