diff --git a/docs/styler-api.mdx b/docs/styler-api.mdx index eaa08744..873fa502 100644 --- a/docs/styler-api.mdx +++ b/docs/styler-api.mdx @@ -39,7 +39,8 @@ final fluent = CardStyler().color(Colors.blue); | Alias of a canonical operation | Do not add one. A canonical operation has exactly one spelling. | | Slot-forwarding convenience (`titleColor`, `labelFontSize`) | Keep it fluent-only. It names a child slot rather than duplicating a canonical operation. | | Styler lifecycle or composition (`animate`, `variants`, `wrap`, `modifier`, `merge`) | Keep it fluent-only because it configures or combines an existing parent styler. | -| Generic variant or callable widget helper | Keep it as an extension method; it operates on an existing styler. | +| Generic variant helper | Keep it as an extension method; it operates on an existing styler. | +| Callable widget helper | Generate it with `@MixableSpec(target: RemixWidget.new)` so it stays aligned with the widget constructor. | | Name conflict | Give the component-specific behavior a descriptive name and reserve the canonical name for the generated surface. | Factories are generated from each component spec. Do not add public methods diff --git a/packages/remix/CHANGELOG.md b/packages/remix/CHANGELOG.md index 47f1633b..8658ca81 100644 --- a/packages/remix/CHANGELOG.md +++ b/packages/remix/CHANGELOG.md @@ -1,5 +1,10 @@ ## 1.0.0-beta.4 +- **BREAKING**: Replace handwritten component `Styler.call(...)` extensions + with generator-owned instance methods. Ordinary `.call(...)` and callable + styler syntax remain source-compatible, but explicit references to the old + `Remix*StylerRemixHelpers` call extensions are removed. +- **FEAT**: Add a generated callable widget surface to `DataTableStyler`. - **BREAKING**: `RemixSelectTrigger` gains `collapsedIcon` and `expandedIcon`, replacing the hardcoded trigger chevron. Each state falls back independently, so a trigger that only sets one keeps the default for the other. diff --git a/packages/remix/lib/src/components/accordion/accordion.g.dart b/packages/remix/lib/src/components/accordion/accordion.g.dart index e05f8585..2cbfd0f6 100644 --- a/packages/remix/lib/src/components/accordion/accordion.g.dart +++ b/packages/remix/lib/src/components/accordion/accordion.g.dart @@ -779,6 +779,47 @@ class AccordionStyler extends MixStyler return merge(AccordionStyler(modifier: value)); } + RemixAccordion call({ + Key? key, + required T value, + required Widget child, + String? title, + IconData? leadingIcon, + IconData? trailingIcon, + NakedAccordionTriggerBuilder? builder, + bool enabled = true, + MouseCursor mouseCursor = SystemMouseCursors.click, + bool enableFeedback = true, + bool autofocus = false, + FocusNode? focusNode, + ValueChanged? onFocusChange, + ValueChanged? onHoverChange, + ValueChanged? onPressChange, + String? semanticLabel, + Widget Function(Widget, Animation)? transitionBuilder, + }) { + return RemixAccordion( + key: key, + style: this, + value: value, + child: child, + title: title, + leadingIcon: leadingIcon, + trailingIcon: trailingIcon, + builder: builder, + enabled: enabled, + mouseCursor: mouseCursor, + enableFeedback: enableFeedback, + autofocus: autofocus, + focusNode: focusNode, + onFocusChange: onFocusChange, + onHoverChange: onHoverChange, + onPressChange: onPressChange, + semanticLabel: semanticLabel, + transitionBuilder: transitionBuilder, + ); + } + /// Merges with another [AccordionStyler]. @override AccordionStyler merge(AccordionStyler? other) { diff --git a/packages/remix/lib/src/components/accordion/accordion_spec.dart b/packages/remix/lib/src/components/accordion/accordion_spec.dart index 10f99ec4..eea52b15 100644 --- a/packages/remix/lib/src/components/accordion/accordion_spec.dart +++ b/packages/remix/lib/src/components/accordion/accordion_spec.dart @@ -1,7 +1,10 @@ part of 'accordion.dart'; /// Resolved visual properties for a [RemixAccordion]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec( + target: RemixAccordion.new, + extraStylerMixins: [RemixBoxStylerMixin], +) class AccordionSpec with _$AccordionSpec { /// Outer panel: radius, border, fill, and clipping shared by [trigger] and /// [content]. diff --git a/packages/remix/lib/src/components/accordion/accordion_style.dart b/packages/remix/lib/src/components/accordion/accordion_style.dart index 47124e2d..bcf7ddd9 100644 --- a/packages/remix/lib/src/components/accordion/accordion_style.dart +++ b/packages/remix/lib/src/components/accordion/accordion_style.dart @@ -103,47 +103,4 @@ extension RemixAccordionStylerRemixHelpers on AccordionStyler { value, ); } - - /// Creates a [RemixAccordion] widget with this style applied. - RemixAccordion call({ - Key? key, - required T value, - required Widget child, - String? title, - IconData? leadingIcon, - IconData? trailingIcon, - NakedAccordionTriggerBuilder? builder, - bool enabled = true, - MouseCursor mouseCursor = SystemMouseCursors.click, - bool enableFeedback = true, - bool autofocus = false, - FocusNode? focusNode, - ValueChanged? onFocusChange, - ValueChanged? onHoverChange, - ValueChanged? onPressChange, - String? semanticLabel, - Widget Function(Widget, Animation)? transitionBuilder, - }) { - return RemixAccordion( - key: key, - value: value, - title: title, - leadingIcon: leadingIcon, - trailingIcon: trailingIcon, - enabled: enabled, - mouseCursor: mouseCursor, - enableFeedback: enableFeedback, - autofocus: autofocus, - focusNode: focusNode, - onFocusChange: onFocusChange, - onHoverChange: onHoverChange, - onPressChange: onPressChange, - semanticLabel: semanticLabel, - transitionBuilder: - transitionBuilder ?? RemixAccordion.defaultAccordionTransitionBuilder, - style: this, - child: child, - builder: builder, - ); - } } diff --git a/packages/remix/lib/src/components/accordion/accordion_widget.dart b/packages/remix/lib/src/components/accordion/accordion_widget.dart index 8205b921..f96a1b19 100644 --- a/packages/remix/lib/src/components/accordion/accordion_widget.dart +++ b/packages/remix/lib/src/components/accordion/accordion_widget.dart @@ -110,10 +110,12 @@ class RemixAccordion extends StatelessWidget { this.onHoverChange, this.onPressChange, this.semanticLabel, - this.transitionBuilder = defaultAccordionTransitionBuilder, + Widget Function(Widget, Animation)? transitionBuilder, this.style = const AccordionStyler.create(), this.styleSpec, - }) : assert( + }) : transitionBuilder = + transitionBuilder ?? defaultAccordionTransitionBuilder, + assert( title != null || builder != null, 'Either title or builder must be provided', ); diff --git a/packages/remix/lib/src/components/avatar/avatar.dart b/packages/remix/lib/src/components/avatar/avatar.dart index fead8e56..c524841b 100644 --- a/packages/remix/lib/src/components/avatar/avatar.dart +++ b/packages/remix/lib/src/components/avatar/avatar.dart @@ -9,6 +9,5 @@ import '../../style/style.dart'; import '../../utilities/remix_style.dart'; part 'avatar_spec.dart'; -part 'avatar_style.dart'; part 'avatar_widget.dart'; part 'avatar.g.dart'; diff --git a/packages/remix/lib/src/components/avatar/avatar.g.dart b/packages/remix/lib/src/components/avatar/avatar.g.dart index a2a73b40..fa3f75c5 100644 --- a/packages/remix/lib/src/components/avatar/avatar.g.dart +++ b/packages/remix/lib/src/components/avatar/avatar.g.dart @@ -639,6 +639,33 @@ class AvatarStyler extends MixStyler return merge(AvatarStyler(modifier: value)); } + RemixAvatar call({ + Key? key, + ImageProvider? backgroundImage, + ImageProvider? foregroundImage, + ImageErrorListener? onBackgroundImageError, + ImageErrorListener? onForegroundImageError, + Widget? child, + String? label, + RemixAvatarLabelBuilder? labelBuilder, + IconData? icon, + RemixAvatarIconBuilder? iconBuilder, + }) { + return RemixAvatar( + key: key, + style: this, + backgroundImage: backgroundImage, + foregroundImage: foregroundImage, + onBackgroundImageError: onBackgroundImageError, + onForegroundImageError: onForegroundImageError, + child: child, + label: label, + labelBuilder: labelBuilder, + icon: icon, + iconBuilder: iconBuilder, + ); + } + /// Merges with another [AvatarStyler]. @override AvatarStyler merge(AvatarStyler? other) { diff --git a/packages/remix/lib/src/components/avatar/avatar_spec.dart b/packages/remix/lib/src/components/avatar/avatar_spec.dart index b6bec47e..d624bffa 100644 --- a/packages/remix/lib/src/components/avatar/avatar_spec.dart +++ b/packages/remix/lib/src/components/avatar/avatar_spec.dart @@ -2,6 +2,7 @@ part of 'avatar.dart'; /// Resolved visual properties for a [RemixAvatar]. @MixableSpec( + target: RemixAvatar.new, extraStylerMixins: [RemixBoxStylerMixin, LabelStyleMixin, IconStyleMixin], ) class AvatarSpec with _$AvatarSpec { diff --git a/packages/remix/lib/src/components/avatar/avatar_style.dart b/packages/remix/lib/src/components/avatar/avatar_style.dart deleted file mode 100644 index f9d176ad..00000000 --- a/packages/remix/lib/src/components/avatar/avatar_style.dart +++ /dev/null @@ -1,32 +0,0 @@ -part of 'avatar.dart'; - -/// Style configuration for [RemixAvatar] container, label, and fallback icon. -extension RemixAvatarStylerRemixHelpers on AvatarStyler { - /// Creates a [RemixAvatar] widget with this style applied. - RemixAvatar call({ - Key? key, - ImageProvider? backgroundImage, - ImageProvider? foregroundImage, - ImageErrorListener? onBackgroundImageError, - ImageErrorListener? onForegroundImageError, - Widget? child, - String? label, - RemixAvatarLabelBuilder? labelBuilder, - IconData? icon, - RemixAvatarIconBuilder? iconBuilder, - }) { - return RemixAvatar( - key: key, - backgroundImage: backgroundImage, - foregroundImage: foregroundImage, - onBackgroundImageError: onBackgroundImageError, - onForegroundImageError: onForegroundImageError, - label: label, - labelBuilder: labelBuilder, - icon: icon, - iconBuilder: iconBuilder, - style: this, - child: child, - ); - } -} diff --git a/packages/remix/lib/src/components/badge/badge.dart b/packages/remix/lib/src/components/badge/badge.dart index 10259582..e823a7c6 100644 --- a/packages/remix/lib/src/components/badge/badge.dart +++ b/packages/remix/lib/src/components/badge/badge.dart @@ -10,6 +10,5 @@ import '../../utilities/remix_style.dart'; import '../../rendering/remix_box_effects.dart'; part 'badge_spec.dart'; -part 'badge_style.dart'; part 'badge_widget.dart'; part 'badge.g.dart'; diff --git a/packages/remix/lib/src/components/badge/badge.g.dart b/packages/remix/lib/src/components/badge/badge.g.dart index b472a855..33c1b526 100644 --- a/packages/remix/lib/src/components/badge/badge.g.dart +++ b/packages/remix/lib/src/components/badge/badge.g.dart @@ -633,6 +633,21 @@ class BadgeStyler extends MixStyler return merge(BadgeStyler(modifier: value)); } + RemixBadge call({ + Key? key, + String? label, + Widget? child, + RemixBadgeLabelBuilder? labelBuilder, + }) { + return RemixBadge( + key: key, + style: this, + label: label, + child: child, + labelBuilder: labelBuilder, + ); + } + /// Merges with another [BadgeStyler]. @override BadgeStyler merge(BadgeStyler? other) { diff --git a/packages/remix/lib/src/components/badge/badge_spec.dart b/packages/remix/lib/src/components/badge/badge_spec.dart index 1e64ba3f..90a9543f 100644 --- a/packages/remix/lib/src/components/badge/badge_spec.dart +++ b/packages/remix/lib/src/components/badge/badge_spec.dart @@ -1,7 +1,10 @@ part of 'badge.dart'; /// Resolved visual properties for a [RemixBadge]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin, LabelStyleMixin]) +@MixableSpec( + target: RemixBadge.new, + extraStylerMixins: [RemixBoxStylerMixin, LabelStyleMixin], +) class BadgeSpec with _$BadgeSpec { @override @MixableField(forwardStyler: true) diff --git a/packages/remix/lib/src/components/badge/badge_style.dart b/packages/remix/lib/src/components/badge/badge_style.dart deleted file mode 100644 index 7bc2d2ed..00000000 --- a/packages/remix/lib/src/components/badge/badge_style.dart +++ /dev/null @@ -1,18 +0,0 @@ -part of 'badge.dart'; - -/// Style configuration for [RemixBadge] container and label text. -extension RemixBadgeStylerRemixHelpers on BadgeStyler { - /// Creates a [RemixBadge] widget with this style applied. - RemixBadge call({ - Key? key, - String? label, - Widget? child, - RemixBadgeLabelBuilder? labelBuilder, - }) => RemixBadge( - key: key, - label: label, - child: child, - labelBuilder: labelBuilder, - style: this, - ); -} diff --git a/packages/remix/lib/src/components/button/button.dart b/packages/remix/lib/src/components/button/button.dart index f5a1b5ff..f7318c07 100644 --- a/packages/remix/lib/src/components/button/button.dart +++ b/packages/remix/lib/src/components/button/button.dart @@ -12,6 +12,5 @@ import '../../utilities/remix_style.dart'; import '../spinner/spinner.dart'; part 'button_spec.dart'; -part 'button_style.dart'; part 'button_widget.dart'; part 'button.g.dart'; diff --git a/packages/remix/lib/src/components/button/button.g.dart b/packages/remix/lib/src/components/button/button.g.dart index fe31aead..ad54dbf3 100644 --- a/packages/remix/lib/src/components/button/button.g.dart +++ b/packages/remix/lib/src/components/button/button.g.dart @@ -759,6 +759,51 @@ class ButtonStyler extends MixStyler return merge(ButtonStyler(modifier: value)); } + RemixButton call({ + Key? key, + required String label, + IconData? leadingIcon, + IconData? trailingIcon, + RemixButtonTextBuilder? textBuilder, + RemixButtonIconBuilder? leadingIconBuilder, + RemixButtonIconBuilder? trailingIconBuilder, + RemixButtonLoadingBuilder? loadingBuilder, + bool loading = false, + bool enabled = true, + VoidCallback? onPressed, + VoidCallback? onLongPress, + FocusNode? focusNode, + bool autofocus = false, + bool enableFeedback = true, + String? semanticLabel, + String? semanticHint, + bool excludeSemantics = false, + MouseCursor mouseCursor = SystemMouseCursors.click, + }) { + return RemixButton( + key: key, + style: this, + label: label, + leadingIcon: leadingIcon, + trailingIcon: trailingIcon, + textBuilder: textBuilder, + leadingIconBuilder: leadingIconBuilder, + trailingIconBuilder: trailingIconBuilder, + loadingBuilder: loadingBuilder, + loading: loading, + enabled: enabled, + onPressed: onPressed, + onLongPress: onLongPress, + focusNode: focusNode, + autofocus: autofocus, + enableFeedback: enableFeedback, + semanticLabel: semanticLabel, + semanticHint: semanticHint, + excludeSemantics: excludeSemantics, + mouseCursor: mouseCursor, + ); + } + /// Merges with another [ButtonStyler]. @override ButtonStyler merge(ButtonStyler? other) { diff --git a/packages/remix/lib/src/components/button/button_spec.dart b/packages/remix/lib/src/components/button/button_spec.dart index 56b386c2..e5058c24 100644 --- a/packages/remix/lib/src/components/button/button_spec.dart +++ b/packages/remix/lib/src/components/button/button_spec.dart @@ -58,6 +58,7 @@ enum RemixIconAlignment { start, end } /// - [RemixButton] for the widget implementation /// - [Spec] for the base specification pattern @MixableSpec( + target: RemixButton.new, extraStylerMixins: [ RemixBoxStylerMixin, LabelStyleMixin, diff --git a/packages/remix/lib/src/components/button/button_style.dart b/packages/remix/lib/src/components/button/button_style.dart deleted file mode 100644 index 963f837d..00000000 --- a/packages/remix/lib/src/components/button/button_style.dart +++ /dev/null @@ -1,54 +0,0 @@ -part of 'button.dart'; - -/// Style builder for [RemixButton]. -/// -/// Use this class to style the button container, label, icons, and loading -/// spinner. It supports Mix variants and widget state variants for focused, -/// hovered, pressed, disabled, and loading states. -extension RemixButtonStylerRemixHelpers on ButtonStyler { - /// Creates a [RemixButton] widget with this style applied. - RemixButton call({ - Key? key, - required String label, - IconData? leadingIcon, - IconData? trailingIcon, - RemixButtonTextBuilder? textBuilder, - RemixButtonIconBuilder? leadingIconBuilder, - RemixButtonIconBuilder? trailingIconBuilder, - RemixButtonLoadingBuilder? loadingBuilder, - bool loading = false, - bool enabled = true, - VoidCallback? onPressed, - VoidCallback? onLongPress, - FocusNode? focusNode, - bool autofocus = false, - bool enableFeedback = true, - String? semanticLabel, - String? semanticHint, - bool excludeSemantics = false, - MouseCursor mouseCursor = SystemMouseCursors.click, - }) { - return RemixButton( - key: key, - label: label, - leadingIcon: leadingIcon, - trailingIcon: trailingIcon, - textBuilder: textBuilder, - leadingIconBuilder: leadingIconBuilder, - trailingIconBuilder: trailingIconBuilder, - loadingBuilder: loadingBuilder, - loading: loading, - enabled: enabled, - onPressed: onPressed, - onLongPress: onLongPress, - focusNode: focusNode, - autofocus: autofocus, - enableFeedback: enableFeedback, - semanticLabel: semanticLabel, - semanticHint: semanticHint, - excludeSemantics: excludeSemantics, - mouseCursor: mouseCursor, - style: this, - ); - } -} diff --git a/packages/remix/lib/src/components/callout/callout.g.dart b/packages/remix/lib/src/components/callout/callout.g.dart index 093fc097..fed8b163 100644 --- a/packages/remix/lib/src/components/callout/callout.g.dart +++ b/packages/remix/lib/src/components/callout/callout.g.dart @@ -715,6 +715,16 @@ class CalloutStyler extends MixStyler return merge(CalloutStyler(modifier: value)); } + RemixCallout call({Key? key, String? text, IconData? icon, Widget? child}) { + return RemixCallout( + key: key, + style: this, + text: text, + icon: icon, + child: child, + ); + } + /// Merges with another [CalloutStyler]. @override CalloutStyler merge(CalloutStyler? other) { diff --git a/packages/remix/lib/src/components/callout/callout_spec.dart b/packages/remix/lib/src/components/callout/callout_spec.dart index 268921fc..8085f2a7 100644 --- a/packages/remix/lib/src/components/callout/callout_spec.dart +++ b/packages/remix/lib/src/components/callout/callout_spec.dart @@ -1,7 +1,10 @@ part of 'callout.dart'; /// Resolved visual values for a [RemixCallout]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin, IconStyleMixin]) +@MixableSpec( + target: RemixCallout.new, + extraStylerMixins: [RemixBoxStylerMixin, IconStyleMixin], +) class CalloutSpec with _$CalloutSpec { @override @MixableField(forwardStyler: true) diff --git a/packages/remix/lib/src/components/callout/callout_style.dart b/packages/remix/lib/src/components/callout/callout_style.dart index aaeeb73e..5fd2b4ef 100644 --- a/packages/remix/lib/src/components/callout/callout_style.dart +++ b/packages/remix/lib/src/components/callout/callout_style.dart @@ -46,15 +46,4 @@ extension RemixCalloutStylerRemixHelpers on CalloutStyler { CalloutStyler textDecorationColor(Color value) { return text(TextStyler(style: TextStyleMix(decorationColor: value))); } - - /// Creates a [RemixCallout] widget with this style applied. - RemixCallout call({Key? key, String? text, IconData? icon, Widget? child}) { - return RemixCallout( - key: key, - text: text, - icon: icon, - style: this, - child: child, - ); - } } diff --git a/packages/remix/lib/src/components/card/card.dart b/packages/remix/lib/src/components/card/card.dart index e8bf46b4..859cd941 100644 --- a/packages/remix/lib/src/components/card/card.dart +++ b/packages/remix/lib/src/components/card/card.dart @@ -9,6 +9,5 @@ import '../../utilities/remix_style.dart'; import '../../rendering/remix_box_effects.dart'; part 'card_spec.dart'; -part 'card_style.dart'; part 'card_widget.dart'; part 'card.g.dart'; diff --git a/packages/remix/lib/src/components/card/card.g.dart b/packages/remix/lib/src/components/card/card.g.dart index b3e16401..21b3bf4a 100644 --- a/packages/remix/lib/src/components/card/card.g.dart +++ b/packages/remix/lib/src/components/card/card.g.dart @@ -616,6 +616,10 @@ class CardStyler extends MixStyler return merge(CardStyler(modifier: value)); } + RemixCard call({Key? key, Widget? child}) { + return RemixCard(key: key, style: this, child: child); + } + /// Merges with another [CardStyler]. @override CardStyler merge(CardStyler? other) { diff --git a/packages/remix/lib/src/components/card/card_spec.dart b/packages/remix/lib/src/components/card/card_spec.dart index 33077c4f..06697f9d 100644 --- a/packages/remix/lib/src/components/card/card_spec.dart +++ b/packages/remix/lib/src/components/card/card_spec.dart @@ -1,7 +1,7 @@ part of 'card.dart'; /// Resolved visual properties for a [RemixCard]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec(target: RemixCard.new, extraStylerMixins: [RemixBoxStylerMixin]) class CardSpec with _$CardSpec { @override @MixableField(forwardStyler: true) diff --git a/packages/remix/lib/src/components/card/card_style.dart b/packages/remix/lib/src/components/card/card_style.dart deleted file mode 100644 index 0ab259ca..00000000 --- a/packages/remix/lib/src/components/card/card_style.dart +++ /dev/null @@ -1,9 +0,0 @@ -part of 'card.dart'; - -/// Style configuration for a [RemixCard] container. -extension RemixCardStylerRemixHelpers on CardStyler { - /// Creates a [RemixCard] widget with this style applied. - RemixCard call({Key? key, Widget? child}) { - return RemixCard(key: key, style: this, child: child); - } -} diff --git a/packages/remix/lib/src/components/checkbox/checkbox.g.dart b/packages/remix/lib/src/components/checkbox/checkbox.g.dart index 9e41cdab..6bbf8a62 100644 --- a/packages/remix/lib/src/components/checkbox/checkbox.g.dart +++ b/packages/remix/lib/src/components/checkbox/checkbox.g.dart @@ -683,6 +683,43 @@ class CheckboxStyler extends MixStyler return merge(CheckboxStyler(modifier: value)); } + RemixCheckbox call({ + Key? key, + required bool? selected, + ValueChanged? onChanged, + bool enabled = true, + bool tristate = false, + IconData? checkedIcon, + IconData? uncheckedIcon, + IconData? indeterminateIcon, + FocusNode? focusNode, + bool autofocus = false, + bool enableFeedback = true, + String? label, + String? semanticLabel, + Size minimumTapTargetSize = const Size.square(48), + MouseCursor mouseCursor = SystemMouseCursors.click, + }) { + return RemixCheckbox( + key: key, + style: this, + selected: selected, + onChanged: onChanged, + enabled: enabled, + tristate: tristate, + checkedIcon: checkedIcon, + uncheckedIcon: uncheckedIcon, + indeterminateIcon: indeterminateIcon, + focusNode: focusNode, + autofocus: autofocus, + enableFeedback: enableFeedback, + label: label, + semanticLabel: semanticLabel, + minimumTapTargetSize: minimumTapTargetSize, + mouseCursor: mouseCursor, + ); + } + /// Merges with another [CheckboxStyler]. @override CheckboxStyler merge(CheckboxStyler? other) { diff --git a/packages/remix/lib/src/components/checkbox/checkbox_spec.dart b/packages/remix/lib/src/components/checkbox/checkbox_spec.dart index 7556bb91..e4476754 100644 --- a/packages/remix/lib/src/components/checkbox/checkbox_spec.dart +++ b/packages/remix/lib/src/components/checkbox/checkbox_spec.dart @@ -56,7 +56,10 @@ part of 'checkbox.dart'; /// - [CheckboxStyler] for the styling API /// - [RemixCheckbox] for the widget implementation /// - [Spec] for the base specification pattern -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin, LabelStyleMixin]) +@MixableSpec( + target: RemixCheckbox.new, + extraStylerMixins: [RemixBoxStylerMixin, LabelStyleMixin], +) class CheckboxSpec with _$CheckboxSpec { /// Styling specification for the checkbox box container. /// diff --git a/packages/remix/lib/src/components/checkbox/checkbox_style.dart b/packages/remix/lib/src/components/checkbox/checkbox_style.dart index 685aad85..dc8ad67c 100644 --- a/packages/remix/lib/src/components/checkbox/checkbox_style.dart +++ b/packages/remix/lib/src/components/checkbox/checkbox_style.dart @@ -25,62 +25,6 @@ extension RemixCheckboxStylerRemixHelpers on CheckboxStyler { ); } - /// Creates a [RemixCheckbox] widget with this style applied. - /// - /// Example: - /// ```dart - /// final checkbox = CheckboxStyler() - /// .fillColor(Colors.blue) - /// .size(24, 24); - /// - /// // Use it like a function - /// checkbox( - /// selected: isChecked, - /// onChanged: (value) => setState(() => isChecked = value), - /// ) - /// ``` - /// - /// This forwarding surface remains explicit because Mix's generated - /// `@MixableSpec(target:)` call requires the target to extend [StyleWidget]. - /// [RemixCheckbox] instead resolves its style inside [NakedCheckbox] with the - /// Naked state controller so state variants stay synchronized. - RemixCheckbox call({ - Key? key, - required bool? selected, - ValueChanged? onChanged, - bool enabled = true, - bool tristate = false, - IconData? checkedIcon, - IconData? uncheckedIcon, - IconData? indeterminateIcon, - FocusNode? focusNode, - bool autofocus = false, - bool enableFeedback = true, - String? label, - String? semanticLabel, - Size minimumTapTargetSize = const Size.square(48), - MouseCursor mouseCursor = SystemMouseCursors.click, - }) { - return RemixCheckbox( - key: key, - selected: selected, - onChanged: onChanged, - enabled: enabled, - tristate: tristate, - checkedIcon: checkedIcon, - uncheckedIcon: uncheckedIcon, - indeterminateIcon: indeterminateIcon, - focusNode: focusNode, - autofocus: autofocus, - enableFeedback: enableFeedback, - label: label, - semanticLabel: semanticLabel, - minimumTapTargetSize: minimumTapTargetSize, - mouseCursor: mouseCursor, - style: this, - ); - } - CheckboxStyler icon(IconStyler value) { return merge(CheckboxStyler(indicator: value)); } diff --git a/packages/remix/lib/src/components/data_table/data_table.g.dart b/packages/remix/lib/src/components/data_table/data_table.g.dart index 2adb5eb4..53501c69 100644 --- a/packages/remix/lib/src/components/data_table/data_table.g.dart +++ b/packages/remix/lib/src/components/data_table/data_table.g.dart @@ -963,6 +963,62 @@ class DataTableStyler extends MixStyler return merge(DataTableStyler(modifier: value)); } + RemixDataTable call({ + Key? key, + required List rows, + required List> columns, + String? semanticLabel, + RemixDataTableSort? sort, + ValueChanged? onSortChanged, + Object Function(T row)? rowId, + Set selectedRowIds = const {}, + ValueChanged>? onSelectionChanged, + int? totalRows, + int pageIndex = 0, + int pageSize = 10, + List pageSizeOptions = const [10, 20, 50], + ValueChanged? onPageChanged, + ValueChanged? onPageSizeChanged, + double minimumWidth = 0, + WidgetBuilder? emptyBuilder, + RemixDataTableLabels labels = const RemixDataTableLabels(), + RemixDataTablePageRangeFormatter pageRangeFormatter = + remixDefaultDataTablePageRangeFormatter, + IconData? sortableIcon, + IconData? sortAscendingIcon, + IconData? sortDescendingIcon, + IconData? previousPageIcon, + IconData? nextPageIcon, + }) { + return RemixDataTable( + key: key, + style: this, + rows: rows, + columns: columns, + semanticLabel: semanticLabel, + sort: sort, + onSortChanged: onSortChanged, + rowId: rowId, + selectedRowIds: selectedRowIds, + onSelectionChanged: onSelectionChanged, + totalRows: totalRows, + pageIndex: pageIndex, + pageSize: pageSize, + pageSizeOptions: pageSizeOptions, + onPageChanged: onPageChanged, + onPageSizeChanged: onPageSizeChanged, + minimumWidth: minimumWidth, + emptyBuilder: emptyBuilder, + labels: labels, + pageRangeFormatter: pageRangeFormatter, + sortableIcon: sortableIcon, + sortAscendingIcon: sortAscendingIcon, + sortDescendingIcon: sortDescendingIcon, + previousPageIcon: previousPageIcon, + nextPageIcon: nextPageIcon, + ); + } + /// Merges with another [DataTableStyler]. @override DataTableStyler merge(DataTableStyler? other) { diff --git a/packages/remix/lib/src/components/data_table/data_table_spec.dart b/packages/remix/lib/src/components/data_table/data_table_spec.dart index cb16840e..90ab8249 100644 --- a/packages/remix/lib/src/components/data_table/data_table_spec.dart +++ b/packages/remix/lib/src/components/data_table/data_table_spec.dart @@ -37,7 +37,10 @@ part of 'data_table.dart'; /// /// Geometry scalars stay null here and default to zero at render time; the /// unopinionated Remix renderer carries no Radix metrics. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec( + target: RemixDataTable.new, + extraStylerMixins: [RemixBoxStylerMixin], +) class DataTableSpec with _$DataTableSpec { /// Outer surface: panel background, border, radius, and clipping. @override diff --git a/packages/remix/lib/src/components/dialog/dialog.dart b/packages/remix/lib/src/components/dialog/dialog.dart index 109cd480..8f9ed0bd 100644 --- a/packages/remix/lib/src/components/dialog/dialog.dart +++ b/packages/remix/lib/src/components/dialog/dialog.dart @@ -11,6 +11,5 @@ import '../../rendering/remix_box_effects.dart'; import '../../utilities/remix_style.dart'; part 'dialog_spec.dart'; -part 'dialog_style.dart'; part 'dialog_widget.dart'; part 'dialog.g.dart'; diff --git a/packages/remix/lib/src/components/dialog/dialog.g.dart b/packages/remix/lib/src/components/dialog/dialog.g.dart index 4b8235e4..8baf03b6 100644 --- a/packages/remix/lib/src/components/dialog/dialog.g.dart +++ b/packages/remix/lib/src/components/dialog/dialog.g.dart @@ -679,6 +679,29 @@ class DialogStyler extends MixStyler return merge(DialogStyler(modifier: value)); } + RemixDialog call({ + Key? key, + Widget? child, + String? title, + String? description, + List? actions, + bool scrollable = false, + bool modal = true, + String? semanticLabel, + }) { + return RemixDialog( + key: key, + style: this, + child: child, + title: title, + description: description, + actions: actions, + scrollable: scrollable, + modal: modal, + semanticLabel: semanticLabel, + ); + } + /// Merges with another [DialogStyler]. @override DialogStyler merge(DialogStyler? other) { diff --git a/packages/remix/lib/src/components/dialog/dialog_spec.dart b/packages/remix/lib/src/components/dialog/dialog_spec.dart index 4c07f82a..99eed5d5 100644 --- a/packages/remix/lib/src/components/dialog/dialog_spec.dart +++ b/packages/remix/lib/src/components/dialog/dialog_spec.dart @@ -1,7 +1,7 @@ part of 'dialog.dart'; /// Resolved visual properties for a [RemixDialog]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec(target: RemixDialog.new, extraStylerMixins: [RemixBoxStylerMixin]) class DialogSpec with _$DialogSpec { @override @MixableField(forwardStyler: true) diff --git a/packages/remix/lib/src/components/dialog/dialog_style.dart b/packages/remix/lib/src/components/dialog/dialog_style.dart deleted file mode 100644 index aaa57529..00000000 --- a/packages/remix/lib/src/components/dialog/dialog_style.dart +++ /dev/null @@ -1,28 +0,0 @@ -part of 'dialog.dart'; - -/// Style configuration for [RemixDialog] container, title, description, and actions. -extension RemixDialogStylerRemixHelpers on DialogStyler { - /// Creates a [RemixDialog] widget with this style applied. - RemixDialog call({ - Key? key, - Widget? child, - String? title, - String? description, - List? actions, - bool scrollable = false, - bool modal = true, - String? semanticLabel, - }) { - return RemixDialog( - key: key, - title: title, - description: description, - actions: actions, - scrollable: scrollable, - modal: modal, - semanticLabel: semanticLabel, - style: this, - child: child, - ); - } -} diff --git a/packages/remix/lib/src/components/divider/divider.g.dart b/packages/remix/lib/src/components/divider/divider.g.dart index 279397ca..0b4018de 100644 --- a/packages/remix/lib/src/components/divider/divider.g.dart +++ b/packages/remix/lib/src/components/divider/divider.g.dart @@ -597,6 +597,10 @@ class DividerStyler extends MixStyler return merge(DividerStyler(modifier: value)); } + RemixDivider call({Key? key}) { + return RemixDivider(key: key, style: this); + } + /// Merges with another [DividerStyler]. @override DividerStyler merge(DividerStyler? other) { diff --git a/packages/remix/lib/src/components/divider/divider_spec.dart b/packages/remix/lib/src/components/divider/divider_spec.dart index bf2a0360..5ea3458b 100644 --- a/packages/remix/lib/src/components/divider/divider_spec.dart +++ b/packages/remix/lib/src/components/divider/divider_spec.dart @@ -1,7 +1,7 @@ part of 'divider.dart'; /// Resolved visual values for a [RemixDivider]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec(target: RemixDivider.new, extraStylerMixins: [RemixBoxStylerMixin]) class DividerSpec with _$DividerSpec { @override @MixableField(forwardStyler: true) diff --git a/packages/remix/lib/src/components/divider/divider_style.dart b/packages/remix/lib/src/components/divider/divider_style.dart index f543aba1..321e34df 100644 --- a/packages/remix/lib/src/components/divider/divider_style.dart +++ b/packages/remix/lib/src/components/divider/divider_style.dart @@ -12,9 +12,4 @@ extension RemixDividerStylerRemixHelpers on DividerStyler { ), ); } - - /// Creates a [RemixDivider] widget with this style applied. - RemixDivider call({Key? key}) { - return RemixDivider(key: key, style: this); - } } diff --git a/packages/remix/lib/src/components/icon_button/icon_button.dart b/packages/remix/lib/src/components/icon_button/icon_button.dart index a9a2e016..7e1149c9 100644 --- a/packages/remix/lib/src/components/icon_button/icon_button.dart +++ b/packages/remix/lib/src/components/icon_button/icon_button.dart @@ -12,6 +12,5 @@ import '../../rendering/remix_box_effects.dart'; import '../spinner/spinner.dart'; part 'icon_button_spec.dart'; -part 'icon_button_style.dart'; part 'icon_button_widget.dart'; part 'icon_button.g.dart'; diff --git a/packages/remix/lib/src/components/icon_button/icon_button.g.dart b/packages/remix/lib/src/components/icon_button/icon_button.g.dart index 14a57c56..e03e32c8 100644 --- a/packages/remix/lib/src/components/icon_button/icon_button.g.dart +++ b/packages/remix/lib/src/components/icon_button/icon_button.g.dart @@ -667,6 +667,43 @@ class IconButtonStyler extends MixStyler return merge(IconButtonStyler(modifier: value)); } + RemixIconButton call({ + Key? key, + required IconData? icon, + RemixIconButtonIconBuilder? iconBuilder, + String? semanticLabel, + RemixIconButtonLoadingBuilder? loadingBuilder, + bool loading = false, + bool enabled = true, + bool enableFeedback = true, + VoidCallback? onPressed, + VoidCallback? onLongPress, + FocusNode? focusNode, + bool autofocus = false, + String? semanticHint, + bool excludeSemantics = false, + MouseCursor mouseCursor = SystemMouseCursors.click, + }) { + return RemixIconButton( + key: key, + style: this, + icon: icon, + iconBuilder: iconBuilder, + semanticLabel: semanticLabel, + loadingBuilder: loadingBuilder, + loading: loading, + enabled: enabled, + enableFeedback: enableFeedback, + onPressed: onPressed, + onLongPress: onLongPress, + focusNode: focusNode, + autofocus: autofocus, + semanticHint: semanticHint, + excludeSemantics: excludeSemantics, + mouseCursor: mouseCursor, + ); + } + /// Merges with another [IconButtonStyler]. @override IconButtonStyler merge(IconButtonStyler? other) { diff --git a/packages/remix/lib/src/components/icon_button/icon_button_spec.dart b/packages/remix/lib/src/components/icon_button/icon_button_spec.dart index 4927275a..a3d50b79 100644 --- a/packages/remix/lib/src/components/icon_button/icon_button_spec.dart +++ b/packages/remix/lib/src/components/icon_button/icon_button_spec.dart @@ -1,7 +1,10 @@ part of 'icon_button.dart'; /// Resolved visual properties for a [RemixIconButton]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin, IconStyleMixin]) +@MixableSpec( + target: RemixIconButton.new, + extraStylerMixins: [RemixBoxStylerMixin, IconStyleMixin], +) class IconButtonSpec with _$IconButtonSpec { @override @MixableField(forwardStyler: true) diff --git a/packages/remix/lib/src/components/icon_button/icon_button_style.dart b/packages/remix/lib/src/components/icon_button/icon_button_style.dart deleted file mode 100644 index 116c5b4a..00000000 --- a/packages/remix/lib/src/components/icon_button/icon_button_style.dart +++ /dev/null @@ -1,41 +0,0 @@ -part of 'icon_button.dart'; - -/// Style configuration for [RemixIconButton] container, icon, and loading spinner. -extension RemixIconButtonStylerRemixHelpers on IconButtonStyler { - RemixIconButton call({ - Key? key, - required IconData? icon, - RemixIconButtonIconBuilder? iconBuilder, - RemixIconButtonLoadingBuilder? loadingBuilder, - bool loading = false, - bool enabled = true, - bool enableFeedback = true, - VoidCallback? onPressed, - VoidCallback? onLongPress, - FocusNode? focusNode, - bool autofocus = false, - String? semanticLabel, - String? semanticHint, - bool excludeSemantics = false, - MouseCursor mouseCursor = SystemMouseCursors.click, - }) { - return RemixIconButton( - key: key, - icon: icon, - iconBuilder: iconBuilder, - loadingBuilder: loadingBuilder, - loading: loading, - enabled: enabled, - enableFeedback: enableFeedback, - onPressed: onPressed, - onLongPress: onLongPress, - focusNode: focusNode, - autofocus: autofocus, - semanticLabel: semanticLabel, - semanticHint: semanticHint, - excludeSemantics: excludeSemantics, - mouseCursor: mouseCursor, - style: this, - ); - } -} diff --git a/packages/remix/lib/src/components/menu/menu.dart b/packages/remix/lib/src/components/menu/menu.dart index b4637c69..34f2b24f 100644 --- a/packages/remix/lib/src/components/menu/menu.dart +++ b/packages/remix/lib/src/components/menu/menu.dart @@ -13,6 +13,5 @@ import '../../utilities/remix_style.dart'; import '../divider/divider.dart'; part 'menu_spec.dart'; -part 'menu_style.dart'; part 'menu_widget.dart'; part 'menu.g.dart'; diff --git a/packages/remix/lib/src/components/menu/menu.g.dart b/packages/remix/lib/src/components/menu/menu.g.dart index 1d8f23f8..5498e82e 100644 --- a/packages/remix/lib/src/components/menu/menu.g.dart +++ b/packages/remix/lib/src/components/menu/menu.g.dart @@ -1113,6 +1113,47 @@ class MenuStyler extends MixStyler { return merge(MenuStyler(modifier: value)); } + RemixMenu call({ + Key? key, + required RemixMenuTrigger trigger, + required List> items, + MenuController? controller, + ValueChanged? onSelected, + VoidCallback? onOpen, + VoidCallback? onClose, + VoidCallback? onCanceled, + RawMenuAnchorOpenRequestedCallback? onOpenRequested, + RawMenuAnchorCloseRequestedCallback? onCloseRequested, + bool consumeOutsideTaps = true, + bool useRootOverlay = false, + bool closeOnClickOutside = true, + FocusNode? triggerFocusNode, + OverlayPositionConfig positioning = const OverlayPositionConfig(), + String? semanticLabel, + bool excludeSemantics = false, + }) { + return RemixMenu( + key: key, + style: this, + trigger: trigger, + items: items, + controller: controller, + onSelected: onSelected, + onOpen: onOpen, + onClose: onClose, + onCanceled: onCanceled, + onOpenRequested: onOpenRequested, + onCloseRequested: onCloseRequested, + consumeOutsideTaps: consumeOutsideTaps, + useRootOverlay: useRootOverlay, + closeOnClickOutside: closeOnClickOutside, + triggerFocusNode: triggerFocusNode, + positioning: positioning, + semanticLabel: semanticLabel, + excludeSemantics: excludeSemantics, + ); + } + /// Merges with another [MenuStyler]. @override MenuStyler merge(MenuStyler? other) { diff --git a/packages/remix/lib/src/components/menu/menu_spec.dart b/packages/remix/lib/src/components/menu/menu_spec.dart index 706fe54e..e7fc8b32 100644 --- a/packages/remix/lib/src/components/menu/menu_spec.dart +++ b/packages/remix/lib/src/components/menu/menu_spec.dart @@ -41,7 +41,7 @@ typedef RemixMenuTriggerSpec = MenuTriggerSpec; /// /// The menu spec owns the trigger, overlay, shared and semantic item styles, /// and divider style used when rendering the menu and its popup content. -@MixableSpec() +@MixableSpec(target: RemixMenu.new) class MenuSpec with _$MenuSpec { /// Style spec for the trigger content. @override diff --git a/packages/remix/lib/src/components/menu/menu_style.dart b/packages/remix/lib/src/components/menu/menu_style.dart deleted file mode 100644 index a748ff7e..00000000 --- a/packages/remix/lib/src/components/menu/menu_style.dart +++ /dev/null @@ -1,61 +0,0 @@ -part of 'menu.dart'; - -/// Style configuration for [RemixMenu] trigger, overlay, shared and semantic -/// item defaults, and dividers. -extension RemixMenuStylerRemixHelpers on MenuStyler { - /// Creates a [RemixMenu] widget with this style applied. - /// - /// Example: - /// ```dart - /// final appMenuStyle = MenuStyler() - /// .trigger(...) - /// .overlay(...) - /// .item(sharedItemStyle) - /// .radioItem(radioItemStyle); - /// - /// return appMenuStyle.call( - /// trigger: RemixMenuTrigger(label: 'Options'), - /// items: [...], - /// ); - /// ``` - RemixMenu call({ - Key? key, - required RemixMenuTrigger trigger, - required List> items, - MenuController? controller, - ValueChanged? onSelected, - VoidCallback? onOpen, - VoidCallback? onClose, - VoidCallback? onCanceled, - RawMenuAnchorOpenRequestedCallback? onOpenRequested, - RawMenuAnchorCloseRequestedCallback? onCloseRequested, - bool consumeOutsideTaps = true, - bool useRootOverlay = false, - bool closeOnClickOutside = true, - FocusNode? triggerFocusNode, - OverlayPositionConfig positioning = const OverlayPositionConfig(), - String? semanticLabel, - bool excludeSemantics = false, - }) { - return RemixMenu( - key: key, - trigger: trigger, - items: items, - controller: controller, - onSelected: onSelected, - onOpen: onOpen, - onClose: onClose, - onCanceled: onCanceled, - onOpenRequested: onOpenRequested, - onCloseRequested: onCloseRequested, - consumeOutsideTaps: consumeOutsideTaps, - useRootOverlay: useRootOverlay, - closeOnClickOutside: closeOnClickOutside, - triggerFocusNode: triggerFocusNode, - positioning: positioning, - semanticLabel: semanticLabel, - excludeSemantics: excludeSemantics, - style: this, - ); - } -} diff --git a/packages/remix/lib/src/components/popover/popover.dart b/packages/remix/lib/src/components/popover/popover.dart index 0a969c6d..8d9a035e 100644 --- a/packages/remix/lib/src/components/popover/popover.dart +++ b/packages/remix/lib/src/components/popover/popover.dart @@ -10,6 +10,5 @@ import '../../rendering/remix_box_effects.dart'; import '../../utilities/remix_style.dart'; part 'popover_spec.dart'; -part 'popover_style.dart'; part 'popover_widget.dart'; part 'popover.g.dart'; diff --git a/packages/remix/lib/src/components/popover/popover.g.dart b/packages/remix/lib/src/components/popover/popover.g.dart index 3c7badcb..091a2995 100644 --- a/packages/remix/lib/src/components/popover/popover.g.dart +++ b/packages/remix/lib/src/components/popover/popover.g.dart @@ -625,6 +625,43 @@ class PopoverStyler extends MixStyler return merge(PopoverStyler(modifier: value)); } + RemixPopover call({ + Key? key, + required Widget popoverChild, + required Widget child, + OverlayPositionConfig positioning = const OverlayPositionConfig(), + bool consumeOutsideTaps = true, + bool useRootOverlay = false, + bool openOnTap = true, + FocusNode? triggerFocusNode, + VoidCallback? onOpen, + VoidCallback? onClose, + RawMenuAnchorOpenRequestedCallback? onOpenRequested, + RawMenuAnchorCloseRequestedCallback? onCloseRequested, + MenuController? controller, + String? semanticLabel, + bool excludeSemantics = false, + }) { + return RemixPopover( + key: key, + style: this, + popoverChild: popoverChild, + child: child, + positioning: positioning, + consumeOutsideTaps: consumeOutsideTaps, + useRootOverlay: useRootOverlay, + openOnTap: openOnTap, + triggerFocusNode: triggerFocusNode, + onOpen: onOpen, + onClose: onClose, + onOpenRequested: onOpenRequested, + onCloseRequested: onCloseRequested, + controller: controller, + semanticLabel: semanticLabel, + excludeSemantics: excludeSemantics, + ); + } + /// Merges with another [PopoverStyler]. @override PopoverStyler merge(PopoverStyler? other) { diff --git a/packages/remix/lib/src/components/popover/popover_spec.dart b/packages/remix/lib/src/components/popover/popover_spec.dart index 07c5c15c..e524b4b0 100644 --- a/packages/remix/lib/src/components/popover/popover_spec.dart +++ b/packages/remix/lib/src/components/popover/popover_spec.dart @@ -1,7 +1,7 @@ part of 'popover.dart'; /// Resolved visual properties for a [RemixPopover] overlay. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec(target: RemixPopover.new, extraStylerMixins: [RemixBoxStylerMixin]) class PopoverSpec with _$PopoverSpec { @override @MixableField(forwardStyler: true) diff --git a/packages/remix/lib/src/components/popover/popover_style.dart b/packages/remix/lib/src/components/popover/popover_style.dart deleted file mode 100644 index 0147fc5b..00000000 --- a/packages/remix/lib/src/components/popover/popover_style.dart +++ /dev/null @@ -1,42 +0,0 @@ -part of 'popover.dart'; - -/// Style configuration for a [RemixPopover] overlay container. -extension RemixPopoverStylerRemixHelpers on PopoverStyler { - /// Creates a [RemixPopover] with this style applied. - RemixPopover call({ - Key? key, - required Widget popoverChild, - required Widget child, - OverlayPositionConfig positioning = const OverlayPositionConfig(), - bool consumeOutsideTaps = true, - bool useRootOverlay = false, - bool openOnTap = true, - FocusNode? triggerFocusNode, - VoidCallback? onOpen, - VoidCallback? onClose, - RawMenuAnchorOpenRequestedCallback? onOpenRequested, - RawMenuAnchorCloseRequestedCallback? onCloseRequested, - MenuController? controller, - String? semanticLabel, - bool excludeSemantics = false, - }) { - return RemixPopover( - key: key, - popoverChild: popoverChild, - positioning: positioning, - consumeOutsideTaps: consumeOutsideTaps, - useRootOverlay: useRootOverlay, - openOnTap: openOnTap, - triggerFocusNode: triggerFocusNode, - onOpen: onOpen, - onClose: onClose, - onOpenRequested: onOpenRequested, - onCloseRequested: onCloseRequested, - controller: controller, - semanticLabel: semanticLabel, - excludeSemantics: excludeSemantics, - style: this, - child: child, - ); - } -} diff --git a/packages/remix/lib/src/components/progress/progress.g.dart b/packages/remix/lib/src/components/progress/progress.g.dart index 3d2a5262..34d772d7 100644 --- a/packages/remix/lib/src/components/progress/progress.g.dart +++ b/packages/remix/lib/src/components/progress/progress.g.dart @@ -700,6 +700,21 @@ class ProgressStyler extends MixStyler return merge(ProgressStyler(modifier: value)); } + RemixProgress call({ + Key? key, + required double value, + String? semanticsLabel, + String? semanticsValue, + }) { + return RemixProgress( + key: key, + style: this, + value: value, + semanticsLabel: semanticsLabel, + semanticsValue: semanticsValue, + ); + } + /// Merges with another [ProgressStyler]. @override ProgressStyler merge(ProgressStyler? other) { diff --git a/packages/remix/lib/src/components/progress/progress_spec.dart b/packages/remix/lib/src/components/progress/progress_spec.dart index b4fcb4cd..ef7cc413 100644 --- a/packages/remix/lib/src/components/progress/progress_spec.dart +++ b/packages/remix/lib/src/components/progress/progress_spec.dart @@ -1,7 +1,10 @@ part of 'progress.dart'; /// Resolved visual values for a [RemixProgress]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec( + target: RemixProgress.new, + extraStylerMixins: [RemixBoxStylerMixin], +) class ProgressSpec with _$ProgressSpec { @override @MixableField(forwardStyler: true) diff --git a/packages/remix/lib/src/components/progress/progress_style.dart b/packages/remix/lib/src/components/progress/progress_style.dart index 27db3664..73f93339 100644 --- a/packages/remix/lib/src/components/progress/progress_style.dart +++ b/packages/remix/lib/src/components/progress/progress_style.dart @@ -22,20 +22,4 @@ extension RemixProgressStylerRemixHelpers on ProgressStyler { ), ); } - - /// Creates a [RemixProgress] widget with this style applied. - RemixProgress call({ - Key? key, - required double value, - String? semanticsLabel, - String? semanticsValue, - }) { - return RemixProgress( - key: key, - value: value, - semanticsLabel: semanticsLabel, - semanticsValue: semanticsValue, - style: this, - ); - } } diff --git a/packages/remix/lib/src/components/radio/radio.g.dart b/packages/remix/lib/src/components/radio/radio.g.dart index dbfeac6f..b9896c56 100644 --- a/packages/remix/lib/src/components/radio/radio.g.dart +++ b/packages/remix/lib/src/components/radio/radio.g.dart @@ -633,6 +633,31 @@ class RadioStyler extends MixStyler return merge(RadioStyler(modifier: value)); } + RemixRadio call({ + Key? key, + required T value, + bool enabled = true, + bool toggleable = false, + MouseCursor? mouseCursor, + FocusNode? focusNode, + bool autofocus = false, + String? semanticLabel, + bool excludeSemantics = false, + }) { + return RemixRadio( + key: key, + style: this, + value: value, + enabled: enabled, + toggleable: toggleable, + mouseCursor: mouseCursor, + focusNode: focusNode, + autofocus: autofocus, + semanticLabel: semanticLabel, + excludeSemantics: excludeSemantics, + ); + } + /// Merges with another [RadioStyler]. @override RadioStyler merge(RadioStyler? other) { diff --git a/packages/remix/lib/src/components/radio/radio_spec.dart b/packages/remix/lib/src/components/radio/radio_spec.dart index 058cb04d..73abe9ad 100644 --- a/packages/remix/lib/src/components/radio/radio_spec.dart +++ b/packages/remix/lib/src/components/radio/radio_spec.dart @@ -5,7 +5,7 @@ part of 'radio.dart'; /// The spec is populated by [RadioStyler] and consumed by the widget when /// building the control. It provides two [StyleSpec] segments representing the /// container (outer ring) and the indicator fill shown when the radio is selected. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec(target: RemixRadio.new, extraStylerMixins: [RemixBoxStylerMixin]) class RadioSpec with _$RadioSpec { @override @MixableField(forwardStyler: true) diff --git a/packages/remix/lib/src/components/radio/radio_style.dart b/packages/remix/lib/src/components/radio/radio_style.dart index 78eecbb7..e1a94c87 100644 --- a/packages/remix/lib/src/components/radio/radio_style.dart +++ b/packages/remix/lib/src/components/radio/radio_style.dart @@ -2,32 +2,6 @@ part of 'radio.dart'; /// Style configuration for [RemixRadio] container and selected indicator. extension RemixRadioStylerRemixHelpers on RadioStyler { - /// Creates a RemixRadio widget with this style applied. - RemixRadio call({ - Key? key, - required T value, - bool enabled = true, - bool toggleable = false, - MouseCursor? mouseCursor, - FocusNode? focusNode, - bool autofocus = false, - String? semanticLabel, - bool excludeSemantics = false, - }) { - return RemixRadio( - key: key, - value: value, - enabled: enabled, - toggleable: toggleable, - mouseCursor: mouseCursor, - focusNode: focusNode, - autofocus: autofocus, - semanticLabel: semanticLabel, - excludeSemantics: excludeSemantics, - style: this, - ); - } - /// Sets fill color on the container. RadioStyler fillColor(Color value) { return merge( diff --git a/packages/remix/lib/src/components/segmented_control/segmented_control.dart b/packages/remix/lib/src/components/segmented_control/segmented_control.dart index 47c583b5..312ff41e 100644 --- a/packages/remix/lib/src/components/segmented_control/segmented_control.dart +++ b/packages/remix/lib/src/components/segmented_control/segmented_control.dart @@ -14,6 +14,5 @@ import '../../style/style.dart'; import '../../utilities/remix_style.dart'; part 'segmented_control_spec.dart'; -part 'segmented_control_style.dart'; part 'segmented_control_widget.dart'; part 'segmented_control.g.dart'; diff --git a/packages/remix/lib/src/components/segmented_control/segmented_control.g.dart b/packages/remix/lib/src/components/segmented_control/segmented_control.g.dart index 600ff004..1683febb 100644 --- a/packages/remix/lib/src/components/segmented_control/segmented_control.g.dart +++ b/packages/remix/lib/src/components/segmented_control/segmented_control.g.dart @@ -778,6 +778,31 @@ class SegmentedControlStyler return merge(SegmentedControlStyler(modifier: value)); } + RemixSegmentedControl call({ + Key? key, + required List> items, + required T? selectedValue, + ValueChanged? onChanged, + bool enabled = true, + Axis orientation = .horizontal, + bool loop = true, + String? semanticLabel, + bool excludeSemantics = false, + }) { + return RemixSegmentedControl( + key: key, + style: this, + items: items, + selectedValue: selectedValue, + onChanged: onChanged, + enabled: enabled, + orientation: orientation, + loop: loop, + semanticLabel: semanticLabel, + excludeSemantics: excludeSemantics, + ); + } + /// Merges with another [SegmentedControlStyler]. @override SegmentedControlStyler merge(SegmentedControlStyler? other) { diff --git a/packages/remix/lib/src/components/segmented_control/segmented_control_spec.dart b/packages/remix/lib/src/components/segmented_control/segmented_control_spec.dart index 8123abf2..d55a17ea 100644 --- a/packages/remix/lib/src/components/segmented_control/segmented_control_spec.dart +++ b/packages/remix/lib/src/components/segmented_control/segmented_control_spec.dart @@ -1,7 +1,10 @@ part of 'segmented_control.dart'; /// Resolved visual properties for a [RemixSegmentedControl]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec( + target: RemixSegmentedControl.new, + extraStylerMixins: [RemixBoxStylerMixin], +) class SegmentedControlSpec with _$SegmentedControlSpec { /// Layout and decoration for the persistent control track. @override diff --git a/packages/remix/lib/src/components/segmented_control/segmented_control_style.dart b/packages/remix/lib/src/components/segmented_control/segmented_control_style.dart deleted file mode 100644 index 6014b2d8..00000000 --- a/packages/remix/lib/src/components/segmented_control/segmented_control_style.dart +++ /dev/null @@ -1,34 +0,0 @@ -part of 'segmented_control.dart'; - -/// Style helpers for [RemixSegmentedControl]. -/// -/// Hand-written rather than generated: `@MixableSpec(target:)` cannot express a -/// generic widget, so generic components carry their own `call` the same way -/// [RemixToggleGroup] and [RemixRadio] do. -extension RemixSegmentedControlStylerRemixHelpers on SegmentedControlStyler { - /// Creates a [RemixSegmentedControl] with this style applied. - RemixSegmentedControl call({ - Key? key, - required List> items, - required T? selectedValue, - ValueChanged? onChanged, - bool enabled = true, - Axis orientation = .horizontal, - bool loop = true, - String? semanticLabel, - bool excludeSemantics = false, - }) { - return RemixSegmentedControl( - key: key, - items: items, - selectedValue: selectedValue, - onChanged: onChanged, - enabled: enabled, - orientation: orientation, - loop: loop, - semanticLabel: semanticLabel, - excludeSemantics: excludeSemantics, - style: this, - ); - } -} diff --git a/packages/remix/lib/src/components/select/select.g.dart b/packages/remix/lib/src/components/select/select.g.dart index 87e5074a..b5484e4c 100644 --- a/packages/remix/lib/src/components/select/select.g.dart +++ b/packages/remix/lib/src/components/select/select.g.dart @@ -957,6 +957,42 @@ class SelectStyler extends MixStyler return merge(SelectStyler(modifier: value)); } + RemixSelect call({ + Key? key, + required RemixSelectTrigger trigger, + required List> items, + T? selectedValue, + OverlayPositionConfig positioning = const OverlayPositionConfig( + side: .bottom, + alignment: .center, + ), + ValueChanged? onChanged, + VoidCallback? onOpen, + VoidCallback? onClose, + bool enabled = true, + MouseCursor mouseCursor = SystemMouseCursors.click, + String? semanticLabel, + bool closeOnSelect = true, + FocusNode? focusNode, + }) { + return RemixSelect( + key: key, + style: this, + trigger: trigger, + items: items, + selectedValue: selectedValue, + positioning: positioning, + onChanged: onChanged, + onOpen: onOpen, + onClose: onClose, + enabled: enabled, + mouseCursor: mouseCursor, + semanticLabel: semanticLabel, + closeOnSelect: closeOnSelect, + focusNode: focusNode, + ); + } + /// Merges with another [SelectStyler]. @override SelectStyler merge(SelectStyler? other) { diff --git a/packages/remix/lib/src/components/select/select_spec.dart b/packages/remix/lib/src/components/select/select_spec.dart index af0bdbb0..126dc468 100644 --- a/packages/remix/lib/src/components/select/select_spec.dart +++ b/packages/remix/lib/src/components/select/select_spec.dart @@ -1,7 +1,7 @@ part of 'select.dart'; /// Resolved visual values for a [RemixSelect]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec(target: RemixSelect.new, extraStylerMixins: [RemixBoxStylerMixin]) class SelectSpec with _$SelectSpec { @override final StyleSpec trigger; diff --git a/packages/remix/lib/src/components/select/select_style.dart b/packages/remix/lib/src/components/select/select_style.dart index b68bdee6..e1b76dd9 100644 --- a/packages/remix/lib/src/components/select/select_style.dart +++ b/packages/remix/lib/src/components/select/select_style.dart @@ -1,59 +1,5 @@ part of 'select.dart'; -/// Style configuration for [RemixSelect] trigger and menu overlay. -extension RemixSelectStylerRemixHelpers on SelectStyler { - /// Creates a [RemixSelect] widget with this style applied. - /// - /// Example: - /// ```dart - /// SelectStyler() - /// .trigger(...) - /// .menuContainer(...) - /// .call( - /// trigger: RemixSelectTrigger(placeholder: 'Select an option'), - /// items: [ - /// RemixSelectItem(value: 'apple', label: 'Apple'), - /// RemixSelectItem(value: 'banana', label: 'Banana'), - /// ], - /// ) - /// ``` - RemixSelect call({ - Key? key, - required RemixSelectTrigger trigger, - required List> items, - T? selectedValue, - OverlayPositionConfig positioning = const OverlayPositionConfig( - side: .bottom, - alignment: .center, - ), - ValueChanged? onChanged, - VoidCallback? onOpen, - VoidCallback? onClose, - bool enabled = true, - MouseCursor mouseCursor = SystemMouseCursors.click, - bool closeOnSelect = true, - String? semanticLabel, - FocusNode? focusNode, - }) { - return RemixSelect( - key: key, - trigger: trigger, - items: items, - selectedValue: selectedValue, - positioning: positioning, - onChanged: onChanged, - onOpen: onOpen, - onClose: onClose, - enabled: enabled, - mouseCursor: mouseCursor, - semanticLabel: semanticLabel, - closeOnSelect: closeOnSelect, - focusNode: focusNode, - style: this, - ); - } -} - /// Style configuration for an item in a [RemixSelect] menu. extension RemixSelectMenuItemStylerRemixHelpers on SelectMenuItemStyler { /// Sets label styling (delegates to text for consistency with mixin) diff --git a/packages/remix/lib/src/components/slider/slider.g.dart b/packages/remix/lib/src/components/slider/slider.g.dart index 6d71f330..0823774c 100644 --- a/packages/remix/lib/src/components/slider/slider.g.dart +++ b/packages/remix/lib/src/components/slider/slider.g.dart @@ -803,6 +803,43 @@ class SliderStyler extends MixStyler return merge(SliderStyler(modifier: value)); } + RemixSlider call({ + Key? key, + required double value, + ValueChanged? onChanged, + ValueChanged? onChangeStart, + ValueChanged? onChangeEnd, + double min = 0.0, + double max = 1.0, + bool enabled = true, + bool enableFeedback = true, + FocusNode? focusNode, + bool autofocus = false, + int? snapDivisions, + String? semanticLabel, + NakedSliderSemanticFormatterCallback? semanticFormatterCallback, + bool excludeSemantics = false, + }) { + return RemixSlider( + key: key, + style: this, + value: value, + onChanged: onChanged, + onChangeStart: onChangeStart, + onChangeEnd: onChangeEnd, + min: min, + max: max, + enabled: enabled, + enableFeedback: enableFeedback, + focusNode: focusNode, + autofocus: autofocus, + snapDivisions: snapDivisions, + semanticLabel: semanticLabel, + semanticFormatterCallback: semanticFormatterCallback, + excludeSemantics: excludeSemantics, + ); + } + /// Merges with another [SliderStyler]. @override SliderStyler merge(SliderStyler? other) { diff --git a/packages/remix/lib/src/components/slider/slider_spec.dart b/packages/remix/lib/src/components/slider/slider_spec.dart index d97ca930..9c206364 100644 --- a/packages/remix/lib/src/components/slider/slider_spec.dart +++ b/packages/remix/lib/src/components/slider/slider_spec.dart @@ -6,7 +6,7 @@ const Color _remixSliderDefaultTrackColor = MixColors.grey; const Color _remixSliderDefaultRangeColor = MixColors.black; /// Resolved visuals for a multi-thumb [RemixSlider]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec(target: RemixSlider.new, extraStylerMixins: [RemixBoxStylerMixin]) class SliderSpec with _$SliderSpec { static const Size defaultThumbSize = _remixSliderDefaultThumbSize; static const double defaultTrackStrokeWidth = diff --git a/packages/remix/lib/src/components/slider/slider_style.dart b/packages/remix/lib/src/components/slider/slider_style.dart index 8964e15d..0f0a24ae 100644 --- a/packages/remix/lib/src/components/slider/slider_style.dart +++ b/packages/remix/lib/src/components/slider/slider_style.dart @@ -36,55 +36,4 @@ extension RemixSliderStylerRemixHelpers on SliderStyler { SliderStyler rangeThickness(double value) { return merge(SliderStyler(rangeWidth: value)); } - - /// Creates a [RemixSlider] widget with this style applied. - /// - /// Example: - /// ```dart - /// final slider = SliderStyler() - /// .thumbColor(Colors.blue) - /// .rangeColor(Colors.blue.shade200); - /// - /// // Use it like a function - /// slider( - /// value: _sliderValue, - /// onChanged: (value) => setState(() => _sliderValue = value), - /// ) - /// ``` - RemixSlider call({ - Key? key, - required double value, - ValueChanged? onChanged, - ValueChanged? onChangeStart, - ValueChanged? onChangeEnd, - double min = 0.0, - double max = 1.0, - bool enabled = true, - bool enableFeedback = true, - FocusNode? focusNode, - bool autofocus = false, - int? snapDivisions, - String? semanticLabel, - NakedSliderSemanticFormatterCallback? semanticFormatterCallback, - bool excludeSemantics = false, - }) { - return RemixSlider( - key: key, - value: value, - onChanged: onChanged, - onChangeStart: onChangeStart, - onChangeEnd: onChangeEnd, - min: min, - max: max, - enabled: enabled, - enableFeedback: enableFeedback, - focusNode: focusNode, - autofocus: autofocus, - snapDivisions: snapDivisions, - semanticLabel: semanticLabel, - semanticFormatterCallback: semanticFormatterCallback, - excludeSemantics: excludeSemantics, - style: this, - ); - } } diff --git a/packages/remix/lib/src/components/spinner/spinner.dart b/packages/remix/lib/src/components/spinner/spinner.dart index 6c34d2fd..040e8e69 100644 --- a/packages/remix/lib/src/components/spinner/spinner.dart +++ b/packages/remix/lib/src/components/spinner/spinner.dart @@ -12,6 +12,5 @@ import '../../utilities/remix_style.dart'; part 'spinner_painter.dart'; part 'spinner_spec.dart'; -part 'spinner_style.dart'; part 'spinner_widget.dart'; part 'spinner.g.dart'; diff --git a/packages/remix/lib/src/components/spinner/spinner.g.dart b/packages/remix/lib/src/components/spinner/spinner.g.dart index 81ad8ba4..c181407d 100644 --- a/packages/remix/lib/src/components/spinner/spinner.g.dart +++ b/packages/remix/lib/src/components/spinner/spinner.g.dart @@ -284,6 +284,19 @@ class SpinnerStyler extends MixStyler { return merge(SpinnerStyler(modifier: value)); } + RemixSpinner call({ + Key? key, + String? semanticsLabel, + String? semanticsValue, + }) { + return RemixSpinner( + key: key, + style: this, + semanticsLabel: semanticsLabel, + semanticsValue: semanticsValue, + ); + } + /// Merges with another [SpinnerStyler]. @override SpinnerStyler merge(SpinnerStyler? other) { diff --git a/packages/remix/lib/src/components/spinner/spinner_spec.dart b/packages/remix/lib/src/components/spinner/spinner_spec.dart index 4e72f344..18d4c9fb 100644 --- a/packages/remix/lib/src/components/spinner/spinner_spec.dart +++ b/packages/remix/lib/src/components/spinner/spinner_spec.dart @@ -1,7 +1,7 @@ part of 'spinner.dart'; /// Resolved visual values for an eight-leaf [RemixSpinner]. -@MixableSpec() +@MixableSpec(target: RemixSpinner.new) class SpinnerSpec with _$SpinnerSpec { @override final double? size; diff --git a/packages/remix/lib/src/components/spinner/spinner_style.dart b/packages/remix/lib/src/components/spinner/spinner_style.dart deleted file mode 100644 index 6414ec6b..00000000 --- a/packages/remix/lib/src/components/spinner/spinner_style.dart +++ /dev/null @@ -1,20 +0,0 @@ -part of 'spinner.dart'; - -/// Style builder for [RemixSpinner]. -/// -/// Use this class to customize spinner size, stroke widths, colors, duration, -/// and Mix variants. -extension RemixSpinnerStylerRemixHelpers on SpinnerStyler { - RemixSpinner call({ - Key? key, - String? semanticsLabel, - String? semanticsValue, - }) { - return RemixSpinner( - key: key, - semanticsLabel: semanticsLabel, - semanticsValue: semanticsValue, - style: this, - ); - } -} diff --git a/packages/remix/lib/src/components/switch/switch.g.dart b/packages/remix/lib/src/components/switch/switch.g.dart index 68072f6e..c72a425d 100644 --- a/packages/remix/lib/src/components/switch/switch.g.dart +++ b/packages/remix/lib/src/components/switch/switch.g.dart @@ -652,6 +652,33 @@ class SwitchStyler extends MixStyler return merge(SwitchStyler(modifier: value)); } + RemixSwitch call({ + Key? key, + required bool selected, + ValueChanged? onChanged, + bool enabled = true, + bool enableFeedback = true, + FocusNode? focusNode, + bool autofocus = false, + String? semanticLabel, + bool excludeSemantics = false, + MouseCursor mouseCursor = SystemMouseCursors.click, + }) { + return RemixSwitch( + key: key, + style: this, + selected: selected, + onChanged: onChanged, + enabled: enabled, + enableFeedback: enableFeedback, + focusNode: focusNode, + autofocus: autofocus, + semanticLabel: semanticLabel, + excludeSemantics: excludeSemantics, + mouseCursor: mouseCursor, + ); + } + /// Merges with another [SwitchStyler]. @override SwitchStyler merge(SwitchStyler? other) { diff --git a/packages/remix/lib/src/components/switch/switch_spec.dart b/packages/remix/lib/src/components/switch/switch_spec.dart index 07ca2bfa..a15f6a5a 100644 --- a/packages/remix/lib/src/components/switch/switch_spec.dart +++ b/packages/remix/lib/src/components/switch/switch_spec.dart @@ -1,7 +1,7 @@ part of 'switch.dart'; /// Resolved visual values for a [RemixSwitch]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec(target: RemixSwitch.new, extraStylerMixins: [RemixBoxStylerMixin]) class SwitchSpec with _$SwitchSpec { @override @MixableField(forwardStyler: true) diff --git a/packages/remix/lib/src/components/switch/switch_style.dart b/packages/remix/lib/src/components/switch/switch_style.dart index fb67cc20..d358c00a 100644 --- a/packages/remix/lib/src/components/switch/switch_style.dart +++ b/packages/remix/lib/src/components/switch/switch_style.dart @@ -18,45 +18,4 @@ extension RemixSwitchStylerRemixHelpers on SwitchStyler { SwitchStyler trackColor(Color value) { return color(value); } - - /// Creates a [RemixSwitch] widget with this style applied. - /// - /// Example: - /// ```dart - /// final toggle = SwitchStyler() - /// .thumbColor(Colors.white) - /// .trackColor(Colors.blue); - /// - /// // Use it like a function - /// toggle( - /// selected: _isEnabled, - /// onChanged: (value) => setState(() => _isEnabled = value), - /// ) - /// ``` - RemixSwitch call({ - Key? key, - required bool selected, - ValueChanged? onChanged, - bool enabled = true, - bool enableFeedback = true, - FocusNode? focusNode, - bool autofocus = false, - String? semanticLabel, - bool excludeSemantics = false, - MouseCursor mouseCursor = SystemMouseCursors.click, - }) { - return RemixSwitch( - key: key, - selected: selected, - onChanged: onChanged, - enabled: enabled, - enableFeedback: enableFeedback, - focusNode: focusNode, - autofocus: autofocus, - semanticLabel: semanticLabel, - excludeSemantics: excludeSemantics, - mouseCursor: mouseCursor, - style: this, - ); - } } diff --git a/packages/remix/lib/src/components/tabs/tabs.dart b/packages/remix/lib/src/components/tabs/tabs.dart index ee7bdb1c..f677f83f 100644 --- a/packages/remix/lib/src/components/tabs/tabs.dart +++ b/packages/remix/lib/src/components/tabs/tabs.dart @@ -11,6 +11,5 @@ import '../../style/style.dart'; import '../../utilities/remix_style.dart'; part 'tabs_spec.dart'; -part 'tabs_style.dart'; part 'tabs_widget.dart'; part 'tabs.g.dart'; diff --git a/packages/remix/lib/src/components/tabs/tabs.g.dart b/packages/remix/lib/src/components/tabs/tabs.g.dart index c2226819..5eb3be86 100644 --- a/packages/remix/lib/src/components/tabs/tabs.g.dart +++ b/packages/remix/lib/src/components/tabs/tabs.g.dart @@ -802,6 +802,10 @@ class TabBarStyler extends MixStyler return merge(TabBarStyler(modifier: value)); } + RemixTabBar call({Key? key, required Widget child}) { + return RemixTabBar(key: key, style: this, child: child); + } + /// Merges with another [TabBarStyler]. @override TabBarStyler merge(TabBarStyler? other) { @@ -1423,6 +1427,43 @@ class TabStyler extends MixStyler return merge(TabStyler(modifier: value)); } + RemixTab call({ + Key? key, + required String tabId, + Widget? child, + String? label, + IconData? icon, + bool enabled = true, + MouseCursor mouseCursor = SystemMouseCursors.click, + bool enableFeedback = true, + FocusNode? focusNode, + bool autofocus = false, + ValueChanged? onFocusChange, + ValueChanged? onHoverChange, + ValueChanged? onPressChange, + ValueWidgetBuilder? builder, + String? semanticLabel, + }) { + return RemixTab( + key: key, + style: this, + tabId: tabId, + child: child, + label: label, + icon: icon, + enabled: enabled, + mouseCursor: mouseCursor, + enableFeedback: enableFeedback, + focusNode: focusNode, + autofocus: autofocus, + onFocusChange: onFocusChange, + onHoverChange: onHoverChange, + onPressChange: onPressChange, + builder: builder, + semanticLabel: semanticLabel, + ); + } + /// Merges with another [TabStyler]. @override TabStyler merge(TabStyler? other) { @@ -1992,6 +2033,21 @@ class TabViewStyler extends MixStyler return merge(TabViewStyler(modifier: value)); } + RemixTabView call({ + Key? key, + required String tabId, + required Widget child, + bool maintainState = true, + }) { + return RemixTabView( + key: key, + style: this, + tabId: tabId, + child: child, + maintainState: maintainState, + ); + } + /// Merges with another [TabViewStyler]. @override TabViewStyler merge(TabViewStyler? other) { diff --git a/packages/remix/lib/src/components/tabs/tabs_spec.dart b/packages/remix/lib/src/components/tabs/tabs_spec.dart index 05cca42d..ac92c757 100644 --- a/packages/remix/lib/src/components/tabs/tabs_spec.dart +++ b/packages/remix/lib/src/components/tabs/tabs_spec.dart @@ -1,7 +1,7 @@ part of 'tabs.dart'; /// Resolved visual values for a [RemixTabBar]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec(target: RemixTabBar.new, extraStylerMixins: [RemixBoxStylerMixin]) class TabBarSpec with _$TabBarSpec { @override @MixableField(forwardStyler: true) @@ -19,6 +19,7 @@ typedef RemixTabBarSpec = TabBarSpec; /// Resolved visual values for an individual [RemixTab]. @MixableSpec( + target: RemixTab.new, extraStylerMixins: [RemixBoxStylerMixin, LabelStyleMixin, IconStyleMixin], ) class TabSpec with _$TabSpec { @@ -46,7 +47,7 @@ class TabSpec with _$TabSpec { typedef RemixTabSpec = TabSpec; /// Resolved visual values for a [RemixTabView]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec(target: RemixTabView.new, extraStylerMixins: [RemixBoxStylerMixin]) class TabViewSpec with _$TabViewSpec { @override @MixableField(forwardStyler: true) diff --git a/packages/remix/lib/src/components/tabs/tabs_style.dart b/packages/remix/lib/src/components/tabs/tabs_style.dart deleted file mode 100644 index f405ac82..00000000 --- a/packages/remix/lib/src/components/tabs/tabs_style.dart +++ /dev/null @@ -1,77 +0,0 @@ -part of 'tabs.dart'; - -/// Style builder for [RemixTabBar]. -/// -/// Use this class to style the flex container that lays out tab triggers. -extension RemixTabBarStylerRemixHelpers on TabBarStyler { - /// Creates a [RemixTabBar] widget with this style applied. - RemixTabBar call({Key? key, required Widget child}) { - return RemixTabBar(key: key, style: this, child: child); - } -} - -/// Style builder for [RemixTabView]. -/// -/// Use this class to style the content container associated with a selected -/// tab. -extension RemixTabViewStylerRemixHelpers on TabViewStyler { - /// Creates a [RemixTabView] widget with this style applied. - RemixTabView call({ - Key? key, - required String tabId, - required Widget child, - bool maintainState = true, - }) { - return RemixTabView( - key: key, - tabId: tabId, - maintainState: maintainState, - style: this, - child: child, - ); - } -} - -/// Style builder for [RemixTab]. -/// -/// Use this class to style an individual tab trigger, including its container, -/// label, icon, and selected state. -extension RemixTabStylerRemixHelpers on TabStyler { - /// Creates a [RemixTab] widget with this style applied. - RemixTab call({ - Key? key, - required String tabId, - Widget? child, - String? label, - IconData? icon, - bool enabled = true, - MouseCursor mouseCursor = SystemMouseCursors.click, - bool enableFeedback = true, - FocusNode? focusNode, - bool autofocus = false, - ValueChanged? onFocusChange, - ValueChanged? onHoverChange, - ValueChanged? onPressChange, - ValueWidgetBuilder? builder, - String? semanticLabel, - }) { - return RemixTab( - key: key, - tabId: tabId, - label: label, - icon: icon, - enabled: enabled, - mouseCursor: mouseCursor, - enableFeedback: enableFeedback, - focusNode: focusNode, - autofocus: autofocus, - onFocusChange: onFocusChange, - onHoverChange: onHoverChange, - onPressChange: onPressChange, - semanticLabel: semanticLabel, - style: this, - child: child, - builder: builder, - ); - } -} diff --git a/packages/remix/lib/src/components/textfield/textfield.g.dart b/packages/remix/lib/src/components/textfield/textfield.g.dart index 3610fcd3..14b93c9f 100644 --- a/packages/remix/lib/src/components/textfield/textfield.g.dart +++ b/packages/remix/lib/src/components/textfield/textfield.g.dart @@ -966,6 +966,129 @@ class TextFieldStyler extends MixStyler return merge(TextFieldStyler(modifier: value)); } + RemixTextField call({ + Key? key, + TextEditingController? controller, + FocusNode? focusNode, + String? label, + String? hintText, + String? helperText, + bool error = false, + TextInputType? keyboardType, + TextInputAction? textInputAction, + TextCapitalization textCapitalization = .none, + TextDirection? textDirection, + bool obscureText = false, + bool enabled = true, + bool readOnly = false, + bool autofocus = false, + int? maxLines = 1, + int? minLines, + bool expands = false, + int? maxLength, + MaxLengthEnforcement? maxLengthEnforcement, + ValueChanged? onChanged, + VoidCallback? onEditingComplete, + ValueChanged? onSubmitted, + AppPrivateCommandCallback? onAppPrivateCommand, + List? inputFormatters, + bool? showCursor, + String obscuringCharacter = '•', + bool autocorrect = true, + bool enableSuggestions = true, + SmartDashesType? smartDashesType, + SmartQuotesType? smartQuotesType, + DragStartBehavior dragStartBehavior = .start, + bool enableInteractiveSelection = true, + TextSelectionControls? selectionControls, + GestureTapCallback? onTap, + TapRegionCallback? onTapOutside, + TapRegionUpCallback? onPressUpOutside, + bool onTapAlwaysCalled = false, + ScrollController? scrollController, + ScrollPhysics? scrollPhysics, + Iterable? autofillHints, + ContentInsertionConfiguration? contentInsertionConfiguration, + Clip clipBehavior = .hardEdge, + String? restorationId, + bool stylusHandwritingEnabled = true, + bool enableIMEPersonalizedLearning = true, + EditableTextContextMenuBuilder? contextMenuBuilder, + SpellCheckConfiguration? spellCheckConfiguration, + TextMagnifierConfiguration? magnifierConfiguration, + bool canRequestFocus = true, + bool? ignorePointers, + UndoHistoryController? undoController, + Object groupId = EditableText, + Widget? leading, + Widget? trailing, + String? semanticLabel, + String? semanticHint, + bool excludeSemantics = false, + }) { + return RemixTextField( + key: key, + style: this, + controller: controller, + focusNode: focusNode, + label: label, + hintText: hintText, + helperText: helperText, + error: error, + keyboardType: keyboardType, + textInputAction: textInputAction, + textCapitalization: textCapitalization, + textDirection: textDirection, + obscureText: obscureText, + enabled: enabled, + readOnly: readOnly, + autofocus: autofocus, + maxLines: maxLines, + minLines: minLines, + expands: expands, + maxLength: maxLength, + maxLengthEnforcement: maxLengthEnforcement, + onChanged: onChanged, + onEditingComplete: onEditingComplete, + onSubmitted: onSubmitted, + onAppPrivateCommand: onAppPrivateCommand, + inputFormatters: inputFormatters, + showCursor: showCursor, + obscuringCharacter: obscuringCharacter, + autocorrect: autocorrect, + enableSuggestions: enableSuggestions, + smartDashesType: smartDashesType, + smartQuotesType: smartQuotesType, + dragStartBehavior: dragStartBehavior, + enableInteractiveSelection: enableInteractiveSelection, + selectionControls: selectionControls, + onTap: onTap, + onTapOutside: onTapOutside, + onPressUpOutside: onPressUpOutside, + onTapAlwaysCalled: onTapAlwaysCalled, + scrollController: scrollController, + scrollPhysics: scrollPhysics, + autofillHints: autofillHints, + contentInsertionConfiguration: contentInsertionConfiguration, + clipBehavior: clipBehavior, + restorationId: restorationId, + stylusHandwritingEnabled: stylusHandwritingEnabled, + enableIMEPersonalizedLearning: enableIMEPersonalizedLearning, + contextMenuBuilder: contextMenuBuilder, + spellCheckConfiguration: spellCheckConfiguration, + magnifierConfiguration: magnifierConfiguration, + canRequestFocus: canRequestFocus, + ignorePointers: ignorePointers, + undoController: undoController, + groupId: groupId, + leading: leading, + trailing: trailing, + semanticLabel: semanticLabel, + semanticHint: semanticHint, + excludeSemantics: excludeSemantics, + ); + } + /// Merges with another [TextFieldStyler]. @override TextFieldStyler merge(TextFieldStyler? other) { diff --git a/packages/remix/lib/src/components/textfield/textfield_spec.dart b/packages/remix/lib/src/components/textfield/textfield_spec.dart index 8f540db1..16883bb6 100644 --- a/packages/remix/lib/src/components/textfield/textfield_spec.dart +++ b/packages/remix/lib/src/components/textfield/textfield_spec.dart @@ -49,7 +49,10 @@ part of 'textfield.dart'; /// - [TextFieldStyler] for the styling API /// - [RemixTextField] for the widget implementation /// - [Spec] for the base specification pattern -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin, LabelStyleMixin]) +@MixableSpec( + target: RemixTextField.new, + extraStylerMixins: [RemixBoxStylerMixin, LabelStyleMixin], +) class TextFieldSpec with _$TextFieldSpec { /// Styling specification for the input text. /// diff --git a/packages/remix/lib/src/components/textfield/textfield_style.dart b/packages/remix/lib/src/components/textfield/textfield_style.dart index 017c07f5..a0460da7 100644 --- a/packages/remix/lib/src/components/textfield/textfield_style.dart +++ b/packages/remix/lib/src/components/textfield/textfield_style.dart @@ -25,141 +25,4 @@ extension RemixTextFieldStylerRemixHelpers on TextFieldStyler { ), ); } - - /// Creates a [RemixTextField] widget with this style applied. - /// - /// Example: - /// ```dart - /// final textField = TextFieldStyler() - /// .color(Colors.grey.shade100) - /// .borderRadius(BorderRadiusMix.circular(8)); - /// - /// // Use it like a function - /// textField( - /// hintText: 'Enter your name', - /// onChanged: (value) => debugPrint(value), - /// ) - /// ``` - RemixTextField call({ - Key? key, - TextEditingController? controller, - FocusNode? focusNode, - String? label, - String? hintText, - String? helperText, - bool error = false, - TextInputType? keyboardType, - TextInputAction? textInputAction, - TextCapitalization textCapitalization = .none, - TextDirection? textDirection, - bool obscureText = false, - bool enabled = true, - bool readOnly = false, - bool autofocus = false, - int? maxLines = 1, - int? minLines, - bool expands = false, - int? maxLength, - MaxLengthEnforcement? maxLengthEnforcement, - ValueChanged? onChanged, - VoidCallback? onEditingComplete, - ValueChanged? onSubmitted, - AppPrivateCommandCallback? onAppPrivateCommand, - List? inputFormatters, - bool? showCursor, - String obscuringCharacter = '•', - bool autocorrect = true, - bool enableSuggestions = true, - SmartDashesType? smartDashesType, - SmartQuotesType? smartQuotesType, - DragStartBehavior dragStartBehavior = .start, - bool enableInteractiveSelection = true, - TextSelectionControls? selectionControls, - GestureTapCallback? onTap, - TapRegionCallback? onTapOutside, - TapRegionUpCallback? onPressUpOutside, - bool onTapAlwaysCalled = false, - ScrollController? scrollController, - ScrollPhysics? scrollPhysics, - Iterable? autofillHints, - ContentInsertionConfiguration? contentInsertionConfiguration, - Clip clipBehavior = .hardEdge, - String? restorationId, - bool stylusHandwritingEnabled = true, - bool enableIMEPersonalizedLearning = true, - EditableTextContextMenuBuilder? contextMenuBuilder, - SpellCheckConfiguration? spellCheckConfiguration, - TextMagnifierConfiguration? magnifierConfiguration, - bool canRequestFocus = true, - bool? ignorePointers, - UndoHistoryController? undoController, - Object groupId = EditableText, - Widget? leading, - Widget? trailing, - String? semanticLabel, - String? semanticHint, - bool excludeSemantics = false, - }) { - return RemixTextField( - key: key, - controller: controller, - focusNode: focusNode, - label: label, - hintText: hintText, - helperText: helperText, - error: error, - keyboardType: keyboardType, - textInputAction: textInputAction, - textCapitalization: textCapitalization, - textDirection: textDirection, - obscureText: obscureText, - enabled: enabled, - readOnly: readOnly, - autofocus: autofocus, - maxLines: maxLines, - minLines: minLines, - expands: expands, - maxLength: maxLength, - maxLengthEnforcement: maxLengthEnforcement, - onChanged: onChanged, - onEditingComplete: onEditingComplete, - onSubmitted: onSubmitted, - onAppPrivateCommand: onAppPrivateCommand, - inputFormatters: inputFormatters, - showCursor: showCursor, - obscuringCharacter: obscuringCharacter, - autocorrect: autocorrect, - enableSuggestions: enableSuggestions, - smartDashesType: smartDashesType, - smartQuotesType: smartQuotesType, - dragStartBehavior: dragStartBehavior, - enableInteractiveSelection: enableInteractiveSelection, - selectionControls: selectionControls, - onTap: onTap, - onTapOutside: onTapOutside, - onPressUpOutside: onPressUpOutside, - onTapAlwaysCalled: onTapAlwaysCalled, - scrollController: scrollController, - scrollPhysics: scrollPhysics, - autofillHints: autofillHints, - contentInsertionConfiguration: contentInsertionConfiguration, - clipBehavior: clipBehavior, - restorationId: restorationId, - stylusHandwritingEnabled: stylusHandwritingEnabled, - enableIMEPersonalizedLearning: enableIMEPersonalizedLearning, - contextMenuBuilder: contextMenuBuilder, - spellCheckConfiguration: spellCheckConfiguration, - magnifierConfiguration: magnifierConfiguration, - canRequestFocus: canRequestFocus, - ignorePointers: ignorePointers, - undoController: undoController, - groupId: groupId, - leading: leading, - trailing: trailing, - semanticLabel: semanticLabel, - semanticHint: semanticHint, - excludeSemantics: excludeSemantics, - style: this, - ); - } } diff --git a/packages/remix/lib/src/components/toggle/toggle.dart b/packages/remix/lib/src/components/toggle/toggle.dart index c60d6e6d..5a25c13a 100644 --- a/packages/remix/lib/src/components/toggle/toggle.dart +++ b/packages/remix/lib/src/components/toggle/toggle.dart @@ -11,6 +11,5 @@ import '../../utilities/remix_style.dart'; import '../../style/style.dart'; part 'toggle_spec.dart'; -part 'toggle_style.dart'; part 'toggle_widget.dart'; part 'toggle.g.dart'; diff --git a/packages/remix/lib/src/components/toggle/toggle.g.dart b/packages/remix/lib/src/components/toggle/toggle.g.dart index 88f589fb..a10fede6 100644 --- a/packages/remix/lib/src/components/toggle/toggle.g.dart +++ b/packages/remix/lib/src/components/toggle/toggle.g.dart @@ -695,6 +695,37 @@ class ToggleStyler extends MixStyler return merge(ToggleStyler(modifier: value)); } + RemixToggle call({ + Key? key, + required bool selected, + ValueChanged? onChanged, + bool enabled = true, + String? label, + IconData? icon, + bool enableFeedback = true, + FocusNode? focusNode, + bool autofocus = false, + String? semanticLabel, + bool excludeSemantics = false, + MouseCursor mouseCursor = SystemMouseCursors.click, + }) { + return RemixToggle( + key: key, + style: this, + selected: selected, + onChanged: onChanged, + enabled: enabled, + label: label, + icon: icon, + enableFeedback: enableFeedback, + focusNode: focusNode, + autofocus: autofocus, + semanticLabel: semanticLabel, + excludeSemantics: excludeSemantics, + mouseCursor: mouseCursor, + ); + } + /// Merges with another [ToggleStyler]. @override ToggleStyler merge(ToggleStyler? other) { diff --git a/packages/remix/lib/src/components/toggle/toggle_spec.dart b/packages/remix/lib/src/components/toggle/toggle_spec.dart index e9eef420..4fb654d1 100644 --- a/packages/remix/lib/src/components/toggle/toggle_spec.dart +++ b/packages/remix/lib/src/components/toggle/toggle_spec.dart @@ -2,6 +2,7 @@ part of 'toggle.dart'; /// Resolved visual properties for a [RemixToggle]. @MixableSpec( + target: RemixToggle.new, extraStylerMixins: [RemixBoxStylerMixin, LabelStyleMixin, IconStyleMixin], ) class ToggleSpec with _$ToggleSpec { diff --git a/packages/remix/lib/src/components/toggle/toggle_style.dart b/packages/remix/lib/src/components/toggle/toggle_style.dart deleted file mode 100644 index ba8aaba5..00000000 --- a/packages/remix/lib/src/components/toggle/toggle_style.dart +++ /dev/null @@ -1,36 +0,0 @@ -part of 'toggle.dart'; - -/// Style configuration for [RemixToggle] container, label, icon, and states. -extension RemixToggleStylerRemixHelpers on ToggleStyler { - /// Creates a [RemixToggle] widget with this style applied. - RemixToggle call({ - Key? key, - required bool selected, - ValueChanged? onChanged, - bool enabled = true, - String? label, - IconData? icon, - bool enableFeedback = true, - FocusNode? focusNode, - bool autofocus = false, - String? semanticLabel, - bool excludeSemantics = false, - MouseCursor mouseCursor = SystemMouseCursors.click, - }) { - return RemixToggle( - key: key, - selected: selected, - onChanged: onChanged, - enabled: enabled, - label: label, - icon: icon, - enableFeedback: enableFeedback, - focusNode: focusNode, - autofocus: autofocus, - semanticLabel: semanticLabel, - excludeSemantics: excludeSemantics, - mouseCursor: mouseCursor, - style: this, - ); - } -} diff --git a/packages/remix/lib/src/components/toggle_group/toggle_group.dart b/packages/remix/lib/src/components/toggle_group/toggle_group.dart index 4da85931..65059593 100644 --- a/packages/remix/lib/src/components/toggle_group/toggle_group.dart +++ b/packages/remix/lib/src/components/toggle_group/toggle_group.dart @@ -10,6 +10,5 @@ import '../../style/style.dart'; import '../../utilities/remix_style.dart'; part 'toggle_group_spec.dart'; -part 'toggle_group_style.dart'; part 'toggle_group_widget.dart'; part 'toggle_group.g.dart'; diff --git a/packages/remix/lib/src/components/toggle_group/toggle_group.g.dart b/packages/remix/lib/src/components/toggle_group/toggle_group.g.dart index e4b2281a..9cab5d54 100644 --- a/packages/remix/lib/src/components/toggle_group/toggle_group.g.dart +++ b/packages/remix/lib/src/components/toggle_group/toggle_group.g.dart @@ -769,6 +769,31 @@ class ToggleGroupStyler extends MixStyler return merge(ToggleGroupStyler(modifier: value)); } + RemixToggleGroup call({ + Key? key, + required List> items, + required T? selectedValue, + ValueChanged? onChanged, + bool enabled = true, + Axis orientation = .horizontal, + bool loop = true, + String? semanticLabel, + bool excludeSemantics = false, + }) { + return RemixToggleGroup( + key: key, + style: this, + items: items, + selectedValue: selectedValue, + onChanged: onChanged, + enabled: enabled, + orientation: orientation, + loop: loop, + semanticLabel: semanticLabel, + excludeSemantics: excludeSemantics, + ); + } + /// Merges with another [ToggleGroupStyler]. @override ToggleGroupStyler merge(ToggleGroupStyler? other) { diff --git a/packages/remix/lib/src/components/toggle_group/toggle_group_spec.dart b/packages/remix/lib/src/components/toggle_group/toggle_group_spec.dart index f68599ba..668cbf91 100644 --- a/packages/remix/lib/src/components/toggle_group/toggle_group_spec.dart +++ b/packages/remix/lib/src/components/toggle_group/toggle_group_spec.dart @@ -1,7 +1,10 @@ part of 'toggle_group.dart'; /// Resolved visual properties for a [RemixToggleGroup]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec( + target: RemixToggleGroup.new, + extraStylerMixins: [RemixBoxStylerMixin], +) class ToggleGroupSpec with _$ToggleGroupSpec { /// Layout and decoration for the group container. @override diff --git a/packages/remix/lib/src/components/toggle_group/toggle_group_style.dart b/packages/remix/lib/src/components/toggle_group/toggle_group_style.dart deleted file mode 100644 index bc123253..00000000 --- a/packages/remix/lib/src/components/toggle_group/toggle_group_style.dart +++ /dev/null @@ -1,30 +0,0 @@ -part of 'toggle_group.dart'; - -/// Style configuration for a [RemixToggleGroup] container and its items. -extension RemixToggleGroupStylerRemixHelpers on ToggleGroupStyler { - /// Creates a [RemixToggleGroup] with this style applied. - RemixToggleGroup call({ - Key? key, - required List> items, - required T? selectedValue, - ValueChanged? onChanged, - bool enabled = true, - Axis orientation = .horizontal, - bool loop = true, - String? semanticLabel, - bool excludeSemantics = false, - }) { - return RemixToggleGroup( - key: key, - items: items, - selectedValue: selectedValue, - onChanged: onChanged, - enabled: enabled, - orientation: orientation, - loop: loop, - semanticLabel: semanticLabel, - excludeSemantics: excludeSemantics, - style: this, - ); - } -} diff --git a/packages/remix/lib/src/components/tooltip/tooltip.dart b/packages/remix/lib/src/components/tooltip/tooltip.dart index ce0f88d4..c8cc234d 100644 --- a/packages/remix/lib/src/components/tooltip/tooltip.dart +++ b/packages/remix/lib/src/components/tooltip/tooltip.dart @@ -9,6 +9,5 @@ import 'package:naked_ui/naked_ui.dart'; import '../../utilities/remix_style.dart'; part 'tooltip_spec.dart'; -part 'tooltip_style.dart'; part 'tooltip_widget.dart'; part 'tooltip.g.dart'; diff --git a/packages/remix/lib/src/components/tooltip/tooltip.g.dart b/packages/remix/lib/src/components/tooltip/tooltip.g.dart index 64d03e17..6c07ae86 100644 --- a/packages/remix/lib/src/components/tooltip/tooltip.g.dart +++ b/packages/remix/lib/src/components/tooltip/tooltip.g.dart @@ -681,6 +681,23 @@ class TooltipStyler extends MixStyler return merge(TooltipStyler(modifier: value)); } + RemixTooltip call({ + Key? key, + required Widget tooltipChild, + required Widget child, + String? tooltipSemantics, + OverlayPositionConfig positioning = const OverlayPositionConfig(), + }) { + return RemixTooltip( + key: key, + style: this, + tooltipChild: tooltipChild, + child: child, + tooltipSemantics: tooltipSemantics, + positioning: positioning, + ); + } + /// Merges with another [TooltipStyler]. @override TooltipStyler merge(TooltipStyler? other) { diff --git a/packages/remix/lib/src/components/tooltip/tooltip_spec.dart b/packages/remix/lib/src/components/tooltip/tooltip_spec.dart index 37d71c8a..a2646588 100644 --- a/packages/remix/lib/src/components/tooltip/tooltip_spec.dart +++ b/packages/remix/lib/src/components/tooltip/tooltip_spec.dart @@ -1,7 +1,7 @@ part of 'tooltip.dart'; /// Resolved visual values for a [RemixTooltip]. -@MixableSpec(extraStylerMixins: [RemixBoxStylerMixin]) +@MixableSpec(target: RemixTooltip.new, extraStylerMixins: [RemixBoxStylerMixin]) class TooltipSpec with _$TooltipSpec { @override @MixableField(forwardStyler: true) diff --git a/packages/remix/lib/src/components/tooltip/tooltip_style.dart b/packages/remix/lib/src/components/tooltip/tooltip_style.dart deleted file mode 100644 index b2fd1f0f..00000000 --- a/packages/remix/lib/src/components/tooltip/tooltip_style.dart +++ /dev/null @@ -1,25 +0,0 @@ -part of 'tooltip.dart'; - -/// Style builder for [RemixTooltip]. -/// -/// Use this class to style tooltip container, label, wait duration, and show -/// duration. -extension RemixTooltipStylerRemixHelpers on TooltipStyler { - /// Creates a [RemixTooltip] widget with this style applied. - RemixTooltip call({ - Key? key, - required Widget tooltipChild, - required Widget child, - String? tooltipSemantics, - OverlayPositionConfig positioning = const OverlayPositionConfig(), - }) { - return RemixTooltip( - key: key, - tooltipChild: tooltipChild, - tooltipSemantics: tooltipSemantics, - positioning: positioning, - style: this, - child: child, - ); - } -} diff --git a/packages/remix/test/components/accordion/accordion_style_test.dart b/packages/remix/test/components/accordion/accordion_style_test.dart index 6a85a0e1..b1bf1fad 100644 --- a/packages/remix/test/components/accordion/accordion_style_test.dart +++ b/packages/remix/test/components/accordion/accordion_style_test.dart @@ -644,6 +644,7 @@ void main() { title: 'Details', child: const Text('Content'), enabled: false, + transitionBuilder: null, ); expect(accordion, isA>()); @@ -652,6 +653,10 @@ void main() { expect(accordion.title, 'Details'); expect(accordion.child, isA()); expect(accordion.enabled, isFalse); + expect( + accordion.transitionBuilder, + same(RemixAccordion.defaultAccordionTransitionBuilder), + ); }); }); diff --git a/packages/remix/test/components/button/button_styler_compatibility_test.dart b/packages/remix/test/components/button/button_styler_compatibility_test.dart index dfa533cb..88156ea3 100644 --- a/packages/remix/test/components/button/button_styler_compatibility_test.dart +++ b/packages/remix/test/components/button/button_styler_compatibility_test.dart @@ -14,9 +14,7 @@ void main() { final legacyFactory = RemixButtonStyler.color(Colors.blue); final ButtonStyler canonical = legacy; - final legacyWidget = RemixButtonStylerRemixHelpers( - legacy, - ).call(label: 'Legacy button'); + final legacyWidget = legacy.call(label: 'Legacy button'); expect(canonical, same(legacy)); expect(legacy.merge(emptyLegacy), isA()); diff --git a/packages/remix/test/components/generated_styler_call_test.dart b/packages/remix/test/components/generated_styler_call_test.dart new file mode 100644 index 00000000..8d8a9b65 --- /dev/null +++ b/packages/remix/test/components/generated_styler_call_test.dart @@ -0,0 +1,59 @@ +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:remix/remix.dart'; + +void main() { + group('generated Styler.call methods', () { + test('forward the owning style for non-generic widgets', () { + final avatarStyle = AvatarStyler(); + final badgeStyle = BadgeStyler(); + final calloutStyle = CalloutStyler(); + final cardStyle = CardStyler(); + final dividerStyle = DividerStyler(); + final popoverStyle = PopoverStyler(); + + expect(avatarStyle.call().style, same(avatarStyle)); + expect(badgeStyle.call().style, same(badgeStyle)); + expect(calloutStyle.call(text: 'Notice').style, same(calloutStyle)); + expect(cardStyle.call().style, same(cardStyle)); + expect(dividerStyle.call().style, same(dividerStyle)); + expect( + popoverStyle + .call( + popoverChild: const SizedBox.shrink(), + child: const SizedBox.shrink(), + ) + .style, + same(popoverStyle), + ); + }); + + test('preserve generic types and forward the owning style', () { + final dataTableStyle = DataTableStyler(); + final segmentedControlStyle = SegmentedControlStyler(); + final table = dataTableStyle.call( + rows: const ['Ada'], + columns: const [ + RemixDataTableColumn( + id: 'name', + label: 'Name', + cellBuilder: _buildCell, + ), + ], + ); + final segmentedControl = segmentedControlStyle.call( + items: const [RemixSegmentedControlItem(value: 'list', label: 'List')], + selectedValue: 'list', + ); + + expect(table, isA>()); + expect(table.style, same(dataTableStyle)); + expect(segmentedControl, isA>()); + expect(segmentedControl.style, same(segmentedControlStyle)); + }); + }); +} + +Widget _buildCell(BuildContext context, String row) { + return Text(row); +} diff --git a/packages/remix/test/components/menu/menu_styler_compatibility_test.dart b/packages/remix/test/components/menu/menu_styler_compatibility_test.dart index 328197dc..9c579a86 100644 --- a/packages/remix/test/components/menu/menu_styler_compatibility_test.dart +++ b/packages/remix/test/components/menu/menu_styler_compatibility_test.dart @@ -112,9 +112,7 @@ void main() { final legacyFactory = RemixMenuStyler.trigger(MenuTriggerStyler()); final MenuStyler canonical = legacy; - final legacyWidget = RemixMenuStylerRemixHelpers( - legacy, - ).call(trigger: trigger, items: items); + final legacyWidget = legacy.call(trigger: trigger, items: items); expect(canonical, same(legacy)); expect(legacy.merge(emptyLegacy), isA()); diff --git a/packages/remix_fortal/example/misc/radix_button_example.dart b/packages/remix_fortal/example/misc/radix_button_example.dart index 06e8d5b2..8cd08e71 100644 --- a/packages/remix_fortal/example/misc/radix_button_example.dart +++ b/packages/remix_fortal/example/misc/radix_button_example.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:remix/remix.dart'; import 'package:remix_fortal/remix_fortal.dart'; void main() { diff --git a/packages/remix_fortal/lib/src/recipes/accordion.g.dart b/packages/remix_fortal/lib/src/recipes/accordion.g.dart index 06578a4b..0fe51a44 100644 --- a/packages/remix_fortal/lib/src/recipes/accordion.g.dart +++ b/packages/remix_fortal/lib/src/recipes/accordion.g.dart @@ -27,7 +27,7 @@ class FortalAccordion extends StatelessWidget { this.onHoverChange, this.onPressChange, this.semanticLabel, - this.transitionBuilder = RemixAccordion.defaultAccordionTransitionBuilder, + this.transitionBuilder, }); const FortalAccordion.surface({ @@ -48,7 +48,7 @@ class FortalAccordion extends StatelessWidget { this.onHoverChange, this.onPressChange, this.semanticLabel, - this.transitionBuilder = RemixAccordion.defaultAccordionTransitionBuilder, + this.transitionBuilder, }) : variant = FortalAccordionVariant.surface; const FortalAccordion.soft({ @@ -69,7 +69,7 @@ class FortalAccordion extends StatelessWidget { this.onHoverChange, this.onPressChange, this.semanticLabel, - this.transitionBuilder = RemixAccordion.defaultAccordionTransitionBuilder, + this.transitionBuilder, }) : variant = FortalAccordionVariant.soft; final FortalAccordionVariant variant; @@ -106,7 +106,7 @@ class FortalAccordion extends StatelessWidget { final String? semanticLabel; - final Widget Function(Widget, Animation) transitionBuilder; + final Widget Function(Widget, Animation)? transitionBuilder; @override Widget build(BuildContext context) { diff --git a/pubspec.lock b/pubspec.lock index 525275c7..7d43ef92 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -457,13 +457,14 @@ packages: source: hosted version: "0.0.1-beta.1" mix_generator: - dependency: transitive + dependency: "direct overridden" description: - name: mix_generator - sha256: "28bf9e71a5a79a02189bec1d5f9d4b0fa560532a36228ff8613272240b091b55" - url: "https://pub.dev" - source: hosted - version: "2.2.0-beta.2" + path: "packages/mix_generator" + ref: "367b1f916498008be89867d0fd192c383f877542" + resolved-ref: "367b1f916498008be89867d0fd192c383f877542" + url: "https://github.com/conceptadev/mix.git" + source: git + version: "2.2.0-beta.3" mustache_template: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 7b56ab62..8df84e56 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,6 +10,14 @@ dev_dependencies: pub_semver: ^2.2.0 yaml: ^3.1.3 +dependency_overrides: + # Remove this pin after conceptadev/mix#1025 ships in mix_generator. + mix_generator: + git: + url: https://github.com/conceptadev/mix.git + ref: 367b1f916498008be89867d0fd192c383f877542 + path: packages/mix_generator + workspace: - apps/dashboard - apps/demo diff --git a/skills/using-remix/references/styling.md b/skills/using-remix/references/styling.md index baa93c74..9a854a44 100644 --- a/skills/using-remix/references/styling.md +++ b/skills/using-remix/references/styling.md @@ -114,11 +114,11 @@ final primaryButton = ButtonStyler() primaryButton(label: 'Save', onPressed: save) // → RemixButton ``` -Generic surfaces use `call()`: Accordion, Menu, Radio, and Select. Dart can -usually infer `T` from the required values or item lists. All other leaf -component stylers use a non-generic `call()` method. Behavioral group/root -widgets such as `RemixAccordionGroup`, `RemixRadioGroup`, and `RemixTabs` are -constructed directly because they do not have stylers. +Generic surfaces use `call()`: Accordion, Menu, Radio, SegmentedControl, +Select, and ToggleGroup. Dart can usually infer `T` from the required values or +item lists. All other leaf component stylers use a non-generic `call()` method. +Behavioral group/root widgets such as `RemixAccordionGroup`, `RemixRadioGroup`, +and `RemixTabs` are constructed directly because they do not have stylers. ### Styling with Fortal Tokens