diff --git a/CHANGELOG.md b/CHANGELOG.md index 369a248..57e0bc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - **FIX**: `ShadSlider` focused thumb. - **FIX**: `ShadResizable` resize when Directionality is RTL. - **FIX**: Update the `destructive` color on dark mode to be more visible. +- **FIX**: Make inherited widget lookup untyped ## 0.16.3 diff --git a/lib/src/components/accordion.dart b/lib/src/components/accordion.dart index 185298b..4f7d5fa 100644 --- a/lib/src/components/accordion.dart +++ b/lib/src/components/accordion.dart @@ -8,6 +8,7 @@ import 'package:shadcn_ui/src/theme/theme.dart'; import 'package:shadcn_ui/src/utils/animation_builder.dart'; import 'package:shadcn_ui/src/utils/effects.dart'; import 'package:shadcn_ui/src/utils/gesture_detector.dart'; +import 'package:shadcn_ui/src/utils/provider.dart'; enum ShadAccordionType { single, @@ -69,8 +70,9 @@ class ShadAccordionState extends State> { @override Widget build(BuildContext context) { - return ShadAccordionInheritedWidget( - data: this, + return ShadProvider( + data: this as ShadAccordionState, + notifyUpdate: (_) => true, child: FocusTraversalGroup( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -82,31 +84,6 @@ class ShadAccordionState extends State> { } } -class ShadAccordionInheritedWidget extends InheritedWidget { - const ShadAccordionInheritedWidget({ - super.key, - required this.data, - required super.child, - }); - - final ShadAccordionState data; - - static ShadAccordionState of(BuildContext context) { - return maybeOf(context)!; - } - - static ShadAccordionState? maybeOf(BuildContext context) { - return context - .dependOnInheritedWidgetOfExactType>() - ?.data; - } - - @override - bool updateShouldNotify(covariant ShadAccordionInheritedWidget oldWidget) { - return true; - } -} - class ShadAccordionItem extends StatefulWidget { const ShadAccordionItem({ super.key, @@ -184,7 +161,7 @@ class _ShadAccordionItemState extends State> @override Widget build(BuildContext context) { - final inherited = ShadAccordionInheritedWidget.of(context); + final inherited = context.watch>(); final expanded = inherited.values.contains(widget.value); final theme = ShadTheme.of(context); final effectiveSeparator = widget.separator ?? const Divider(); diff --git a/lib/src/components/input_otp.dart b/lib/src/components/input_otp.dart index ace6b91..425b266 100644 --- a/lib/src/components/input_otp.dart +++ b/lib/src/components/input_otp.dart @@ -229,10 +229,7 @@ class ShadInputOTPGroup extends StatefulWidget { } class _ShadInputOTPGroupState extends State { - late final otpProvider = ShadProvider.of( - context, - listen: false, - ); + late final otpProvider = context.read(); @override void initState() { @@ -349,10 +346,7 @@ class ShadInputOTPSlot extends StatefulWidget { } class _ShadInputOTPSlotState extends State { - late final otpProvider = ShadProvider.of( - context, - listen: false, - ); + late final otpProvider = context.read(); // ignore: use_late_for_private_fields_and_variables FocusNode? _focusNode; @@ -404,7 +398,7 @@ class _ShadInputOTPSlotState extends State { final theme = ShadTheme.of(context); // Watching the OTP provider for changes - final otpProvider = ShadProvider.of(context); + final otpProvider = context.watch(); final defaultStyle = widget.style ?? theme.inputOTPTheme.style ?? diff --git a/lib/src/components/radio.dart b/lib/src/components/radio.dart index 50ec65d..ff50481 100644 --- a/lib/src/components/radio.dart +++ b/lib/src/components/radio.dart @@ -7,6 +7,7 @@ import 'package:shadcn_ui/src/raw_components/focusable.dart'; import 'package:shadcn_ui/src/theme/components/decorator.dart'; import 'package:shadcn_ui/src/theme/theme.dart'; import 'package:shadcn_ui/src/utils/debug_check.dart'; +import 'package:shadcn_ui/src/utils/provider.dart'; class ShadRadioGroup extends StatefulWidget { const ShadRadioGroup({ @@ -78,17 +79,6 @@ class ShadRadioGroup extends StatefulWidget { @override State> createState() => ShadRadioGroupState(); - - static ShadRadioGroupState of(BuildContext context) { - return maybeOf(context)!; - } - - static ShadRadioGroupState? maybeOf(BuildContext context) { - return context - .dependOnInheritedWidgetOfExactType< - ShadInheritedRadioGroupContainer>() - ?.data; - } } class ShadRadioGroupState extends State> { @@ -126,8 +116,9 @@ class ShadRadioGroupState extends State> { theme.radioTheme.crossAxisAlignment ?? WrapCrossAlignment.start; - return ShadInheritedRadioGroupContainer( - data: this, + return ShadProvider( + data: this as ShadRadioGroupState, + notifyUpdate: (_) => true, child: Wrap( direction: effectiveAxis, spacing: effectiveSpacing, @@ -141,20 +132,6 @@ class ShadRadioGroupState extends State> { } } -class ShadInheritedRadioGroupContainer extends InheritedWidget { - const ShadInheritedRadioGroupContainer({ - super.key, - required this.data, - required super.child, - }); - - final ShadRadioGroupState data; - - @override - bool updateShouldNotify(ShadInheritedRadioGroupContainer oldWidget) => - true; -} - class ShadRadio extends StatefulWidget { const ShadRadio({ super.key, @@ -233,12 +210,8 @@ class _ShadRadioState extends State> { @override Widget build(BuildContext context) { assert(debugCheckHasShadTheme(context)); - assert( - ShadRadioGroup.maybeOf(context) != null, - 'Cannot find ShadRadioGroup InheritedWidget', - ); final theme = ShadTheme.of(context); - final inheritedRadioGroup = ShadRadioGroup.of(context); + final inheritedRadioGroup = context.watch>(); void onTap() { inheritedRadioGroup.select(widget.value); diff --git a/lib/src/components/select.dart b/lib/src/components/select.dart index 3a95adf..8c959c7 100644 --- a/lib/src/components/select.dart +++ b/lib/src/components/select.dart @@ -17,6 +17,7 @@ import 'package:shadcn_ui/src/theme/components/select.dart'; import 'package:shadcn_ui/src/theme/theme.dart'; import 'package:shadcn_ui/src/utils/debug_check.dart'; import 'package:shadcn_ui/src/utils/gesture_detector.dart'; +import 'package:shadcn_ui/src/utils/provider.dart'; typedef ShadSelectedOptionBuilder = Widget Function( BuildContext context, @@ -450,27 +451,6 @@ class ShadSelect extends StatefulWidget { /// {@endtemplate} final bool? shrinkWrap; - static ShadSelectState of(BuildContext context, {bool listen = true}) { - return maybeOf(context, listen: listen)!; - } - - static ShadSelectState? maybeOf( - BuildContext context, { - bool listen = true, - }) { - if (listen) { - return context - .dependOnInheritedWidgetOfExactType>() - ?.data; - } - final provider = context - .getElementForInheritedWidgetOfExactType< - ShadInheritedSelectContainer>() - ?.widget; - - return (provider as ShadInheritedSelectContainer?)?.data; - } - @override ShadSelectState createState() => ShadSelectState(); } @@ -867,8 +847,9 @@ class ShadSelectState extends State> { ) : null; - return ShadInheritedSelectContainer( - data: this, + return ShadProvider( + data: this as ShadSelectState, + notifyUpdate: (_) => true, child: ShadPopover( groupId: widget.groupId, padding: EdgeInsets.zero, @@ -948,19 +929,6 @@ class ShadSelectState extends State> { } } -class ShadInheritedSelectContainer extends InheritedWidget { - const ShadInheritedSelectContainer({ - super.key, - required this.data, - required super.child, - }); - - final ShadSelectState data; - - @override - bool updateShouldNotify(ShadInheritedSelectContainer oldWidget) => true; -} - class ShadOption extends StatefulWidget { const ShadOption({ super.key, @@ -1005,7 +973,7 @@ class _ShadOptionState extends State> { super.initState(); focusNode.addListener(onFocusChange); - final inherited = ShadSelect.of(context, listen: false); + final inherited = context.read>(); final selected = inherited.selectedValues.contains(widget.value); if (selected) focusNode.requestFocus(); } @@ -1026,11 +994,7 @@ class _ShadOptionState extends State> { @override Widget build(BuildContext context) { final theme = ShadTheme.of(context); - assert( - ShadSelect.maybeOf(context) != null, - 'Cannot find ShadSelect InheritedWidget', - ); - final inheritedSelect = ShadSelect.of(context); + final inheritedSelect = context.watch>(); final selected = inheritedSelect.selectedValues.contains(widget.value); if (selected) { diff --git a/lib/src/components/tabs.dart b/lib/src/components/tabs.dart index fb17977..7222948 100644 --- a/lib/src/components/tabs.dart +++ b/lib/src/components/tabs.dart @@ -8,37 +8,9 @@ import 'package:shadcn_ui/src/theme/theme.dart'; import 'package:shadcn_ui/src/theme/themes/shadows.dart'; import 'package:shadcn_ui/src/utils/border.dart'; import 'package:shadcn_ui/src/utils/gesture_detector.dart'; +import 'package:shadcn_ui/src/utils/provider.dart'; import 'package:shadcn_ui/src/utils/states_controller.dart'; -class ShadTabsInheritedWidget extends InheritedWidget { - const ShadTabsInheritedWidget({ - super.key, - required this.data, - required super.child, - }); - - final ShadTabsState data; - - static ShadTabsState of(BuildContext context) { - final provider = maybeOf(context); - if (provider == null) { - throw FlutterError('No ShadTabs widget found in context'); - } - return provider; - } - - static ShadTabsState? maybeOf(BuildContext context) { - return context - .dependOnInheritedWidgetOfExactType>() - ?.data; - } - - @override - bool updateShouldNotify(covariant ShadTabsInheritedWidget oldWidget) { - return true; - } -} - class ShadTabsController extends ChangeNotifier { ShadTabsController({required T value}) : selected = value; @@ -323,8 +295,9 @@ class ShadTabsState extends State> with RestorationMixin { tabBar = Padding(padding: effectivePadding, child: tabBar); } - return ShadTabsInheritedWidget( - data: this, + return ShadProvider( + data: this as ShadTabsState, + notifyUpdate: (_) => true, child: ListenableBuilder( listenable: controller, builder: (context, _) { @@ -620,7 +593,7 @@ class _ShadTabState extends State> { @override Widget build(BuildContext context) { final theme = ShadTheme.of(context); - final inherited = ShadTabsInheritedWidget.of(context); + final inherited = context.watch>(); final tabsTheme = theme.tabsTheme; diff --git a/lib/src/components/toast.dart b/lib/src/components/toast.dart index aec9329..d061cac 100644 --- a/lib/src/components/toast.dart +++ b/lib/src/components/toast.dart @@ -25,7 +25,13 @@ class ShadToaster extends StatefulWidget { State createState() => ShadToasterState(); static ShadToasterState of(BuildContext context) { - return maybeOf(context)!; + final provider = maybeOf(context); + if (provider == null) { + throw FlutterError( + '''Could not find ShadToaster InheritedWidget in the ancestor widget tree.''', + ); + } + return provider; } static ShadToasterState? maybeOf(BuildContext context) {