diff --git a/CHANGELOG.md b/CHANGELOG.md index e3f1683..cb61646 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +## 3.0.2 + +- `UIComponent`: + - Added private `_subComponent` flag to distinguish subcomponents. + - Refactored constructors: + - Added private named constructor `UIComponent._` to centralize initialization. + - Added public mirror constructor `UIComponent` with detailed documentation on parameters controlling rendering, styling, and structure. + - Added new constructor `UIComponent.subComponent` for creating components attached to an existing `parentComponent`, sharing its DOM mapping context. + - Updated `dispose` method to avoid disposing shared `domTreeMap` when the component is a subcomponent. + +- `UIButton` (`button.dart`): + - Extended `$uiButtonLoader` function to support additional attributes for loaded text styling and content: + - Added parameters: `loadedTextClass`, `loadedTextStyle`, `loadedTextErrorClass`, `loadedTextErrorStyle`, `loadedTextOK`, `loadedTextError`. + - Added corresponding attributes to the returned DOM element for these new parameters. + ## 3.0.1 - `UIComponent`: diff --git a/lib/src/bones_ui.dart b/lib/src/bones_ui.dart index 563e574..356db4c 100644 --- a/lib/src/bones_ui.dart +++ b/lib/src/bones_ui.dart @@ -1,3 +1,3 @@ class BonesUI { - static const String version = '3.0.1'; + static const String version = '3.0.2'; } diff --git a/lib/src/bones_ui_component.dart b/lib/src/bones_ui_component.dart index 379d448..1eb59ec 100644 --- a/lib/src/bones_ui_component.dart +++ b/lib/src/bones_ui_component.dart @@ -83,8 +83,12 @@ abstract class UIComponent extends UIEventHandler { bool? get constructing => _constructing; - UIComponent(Object? parent, - {dynamic componentClass, + final bool _subComponent; + + UIComponent._(Object? parent, + {bool subComponent = false, + UIComponent? parentComponent, + dynamic componentClass, dynamic componentStyle, dynamic classes, dynamic classes2, @@ -98,7 +102,12 @@ abstract class UIComponent extends UIEventHandler { this.id, UIComponentGenerator? generator}) : globalID = ++_globalIDCount, + _subComponent = subComponent, _generator = generator { + if (subComponent) { + _domTreeMap = parentComponent?.domTreeMap; + } + _resolveParent(parent); if (construct) { @@ -107,6 +116,121 @@ abstract class UIComponent extends UIEventHandler { } } + /// Creates a UI component. + /// + /// The optional [parent] is the DOM target or logical container where the + /// component will be inserted. If null, it will be defined by the component + /// that encapsulates this one during render. + /// + /// Rendering behavior: + /// * [construct] builds the element immediately. + /// * [renderOnConstruction] renders right after construction. + /// * [preserveRender] preserves previously rendered elements in future renders. + /// * [inline] creates the [content] element as inline. + /// + /// Styling: + /// * [componentClass] / [componentStyle] default values applied to the + /// [content] element. + /// * [classes] / [classes2] are merged CSS classes. + /// * [style] / [style2] are merged style declarations. + /// + /// Structure control: + /// * [clearParent] optionally clears the container before insertion. + /// * [generator] the [UIComponentGenerator] used to generate [DOMNode] elements. + /// * [id] the ID of the component instance (not applied to the [content] element). + UIComponent( + Object? parent, { + dynamic componentClass, + dynamic componentStyle, + dynamic classes, + dynamic classes2, + dynamic style, + dynamic style2, + UIComponentClearParent? clearParent, + bool inline = true, + bool construct = true, + bool renderOnConstruction = false, + bool preserveRender = false, + dynamic id, + UIComponentGenerator? generator, + }) : this._( + parent, + componentClass: componentClass, + componentStyle: componentStyle, + classes: classes, + classes2: classes2, + style: style, + style2: style2, + clearParent: clearParent, + inline: inline, + construct: construct, + renderOnConstruction: renderOnConstruction, + preserveRender: preserveRender, + id: id, + generator: generator, + ); + + /// Creates a component attached to an existing [parentComponent]. + /// + /// This constructor establishes a hierarchical relationship: the new instance + /// becomes part of the parent component render tree and shares its DOM mapping + /// context ([domTreeMap]). It should be used for composition inside another + /// component rather than for standalone roots. + /// + /// The optional [parent] is the DOM target used during creation. If null, + /// the parent component defines the insertion point when rendering. + /// + /// Rendering behavior: + /// * [construct] builds the element immediately. + /// * [renderOnConstruction] renders right after construction. + /// * [preserveRender] preserves previously rendered elements in future renders. + /// * [inline] creates the [content] element as inline. + /// + /// Styling: + /// * [componentClass] / [componentStyle] default values applied to the + /// [content] element. + /// * [classes] / [classes2] are merged CSS classes. + /// * [style] / [style2] are merged style declarations. + /// + /// Structure control: + /// * [clearParent] optionally clears the container before insertion. + /// * [generator] the [UIComponentGenerator] used to generate [DOMNode] elements. + /// * [id] the ID of the component instance (not applied to the [content] element). + UIComponent.subComponent( + Object? parent, { + required UIComponent parentComponent, + dynamic componentClass, + dynamic componentStyle, + dynamic classes, + dynamic classes2, + dynamic style, + dynamic style2, + UIComponentClearParent? clearParent, + bool inline = true, + bool construct = true, + bool renderOnConstruction = false, + bool preserveRender = false, + dynamic id, + UIComponentGenerator? generator, + }) : this._( + parent, + subComponent: true, + parentComponent: parentComponent, + componentClass: componentClass, + componentStyle: componentStyle, + classes: classes, + classes2: classes2, + style: style, + style2: style2, + clearParent: clearParent, + inline: inline, + construct: construct, + renderOnConstruction: renderOnConstruction, + preserveRender: preserveRender, + id: id, + generator: generator, + ); + void _resolveParent(Object? parent) { _resolveParentUIComponent(parent); @@ -3295,7 +3419,9 @@ abstract class UIComponent extends UIEventHandler { if (!preserveRender) { final domTreeMap = _domTreeMap; if (domTreeMap != null) { - domTreeMap.dispose(); + if (!_subComponent) { + domTreeMap.dispose(); + } _domTreeMap = null; } diff --git a/lib/src/component/button.dart b/lib/src/component/button.dart index 4e03862..0d12830 100644 --- a/lib/src/component/button.dart +++ b/lib/src/component/button.dart @@ -276,6 +276,12 @@ DOMElement $uiButtonLoader( Map? attributes, content, bool commented = false, + loadedTextClass, + loadedTextStyle, + loadedTextErrorClass, + loadedTextErrorStyle, + loadedTextOK, + loadedTextError, bool? withProgress, dynamic loadingConfig}) { return $tag( @@ -290,6 +296,18 @@ DOMElement $uiButtonLoader( parseStringFromInlineList(buttonClasses)?.join(',') ?? '', if (buttonClasses != null) 'button-style': CSS(buttonStyle).style, if (withProgress != null) 'with-progress': '$withProgress', + if (loadedTextStyle != null) + 'loaded-text-style': CSS(loadedTextStyle).style, + if (loadedTextClass != null) + 'loaded-text-classes': + parseStringFromInlineList(buttonClasses)?.join(',') ?? '', + if (loadedTextErrorStyle != null) + 'loaded-text-error-style': CSS(loadedTextErrorStyle).style, + if (loadedTextErrorClass != null) + 'loaded-text-error-classes': + parseStringFromInlineList(loadedTextErrorClass)?.join(',') ?? '', + if (loadedTextOK != null) 'loaded-text-ok': '$loadedTextOK', + if (loadedTextError != null) 'loaded-text-error': '$loadedTextError', if (loadingConfig != null) 'loading-config': (loadingConfig is UILoadingConfig ? loadingConfig.toInlineProperties() diff --git a/pubspec.yaml b/pubspec.yaml index fe734b4..81c2164 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: bones_ui description: Bones_UI - An intuitive and user-friendly Web User Interface framework for Dart. -version: 3.0.1 +version: 3.0.2 homepage: https://github.com/Colossus-Services/bones_ui environment: