Skip to content

Commit

Permalink
fix: inherited widget lookup untyped
Browse files Browse the repository at this point in the history
  • Loading branch information
nank1ro committed Dec 30, 2024
1 parent 242be73 commit 17722c5
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 144 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
33 changes: 5 additions & 28 deletions lib/src/components/accordion.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -69,8 +70,9 @@ class ShadAccordionState<T> extends State<ShadAccordion<T>> {

@override
Widget build(BuildContext context) {
return ShadAccordionInheritedWidget<T>(
data: this,
return ShadProvider(
data: this as ShadAccordionState<dynamic>,
notifyUpdate: (_) => true,
child: FocusTraversalGroup(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
Expand All @@ -82,31 +84,6 @@ class ShadAccordionState<T> extends State<ShadAccordion<T>> {
}
}

class ShadAccordionInheritedWidget<T> extends InheritedWidget {
const ShadAccordionInheritedWidget({
super.key,
required this.data,
required super.child,
});

final ShadAccordionState<T> data;

static ShadAccordionState<T> of<T>(BuildContext context) {
return maybeOf<T>(context)!;
}

static ShadAccordionState<T>? maybeOf<T>(BuildContext context) {
return context
.dependOnInheritedWidgetOfExactType<ShadAccordionInheritedWidget<T>>()
?.data;
}

@override
bool updateShouldNotify(covariant ShadAccordionInheritedWidget<T> oldWidget) {
return true;
}
}

class ShadAccordionItem<T> extends StatefulWidget {
const ShadAccordionItem({
super.key,
Expand Down Expand Up @@ -184,7 +161,7 @@ class _ShadAccordionItemState<T> extends State<ShadAccordionItem<T>>

@override
Widget build(BuildContext context) {
final inherited = ShadAccordionInheritedWidget.of<T>(context);
final inherited = context.watch<ShadAccordionState<dynamic>>();
final expanded = inherited.values.contains(widget.value);
final theme = ShadTheme.of(context);
final effectiveSeparator = widget.separator ?? const Divider();
Expand Down
12 changes: 3 additions & 9 deletions lib/src/components/input_otp.dart
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,7 @@ class ShadInputOTPGroup extends StatefulWidget {
}

class _ShadInputOTPGroupState extends State<ShadInputOTPGroup> {
late final otpProvider = ShadProvider.of<ShadInputOTPState>(
context,
listen: false,
);
late final otpProvider = context.read<ShadInputOTPState>();

@override
void initState() {
Expand Down Expand Up @@ -349,10 +346,7 @@ class ShadInputOTPSlot extends StatefulWidget {
}

class _ShadInputOTPSlotState extends State<ShadInputOTPSlot> {
late final otpProvider = ShadProvider.of<ShadInputOTPState>(
context,
listen: false,
);
late final otpProvider = context.read<ShadInputOTPState>();

// ignore: use_late_for_private_fields_and_variables
FocusNode? _focusNode;
Expand Down Expand Up @@ -404,7 +398,7 @@ class _ShadInputOTPSlotState extends State<ShadInputOTPSlot> {
final theme = ShadTheme.of(context);

// Watching the OTP provider for changes
final otpProvider = ShadProvider.of<ShadInputOTPState>(context);
final otpProvider = context.watch<ShadInputOTPState>();

final defaultStyle = widget.style ??
theme.inputOTPTheme.style ??
Expand Down
37 changes: 5 additions & 32 deletions lib/src/components/radio.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> extends StatefulWidget {
const ShadRadioGroup({
Expand Down Expand Up @@ -78,17 +79,6 @@ class ShadRadioGroup<T> extends StatefulWidget {

@override
State<ShadRadioGroup<T>> createState() => ShadRadioGroupState<T>();

static ShadRadioGroupState<T> of<T>(BuildContext context) {
return maybeOf<T>(context)!;
}

static ShadRadioGroupState<T>? maybeOf<T>(BuildContext context) {
return context
.dependOnInheritedWidgetOfExactType<
ShadInheritedRadioGroupContainer<T>>()
?.data;
}
}

class ShadRadioGroupState<T> extends State<ShadRadioGroup<T>> {
Expand Down Expand Up @@ -126,8 +116,9 @@ class ShadRadioGroupState<T> extends State<ShadRadioGroup<T>> {
theme.radioTheme.crossAxisAlignment ??
WrapCrossAlignment.start;

return ShadInheritedRadioGroupContainer(
data: this,
return ShadProvider(
data: this as ShadRadioGroupState<dynamic>,
notifyUpdate: (_) => true,
child: Wrap(
direction: effectiveAxis,
spacing: effectiveSpacing,
Expand All @@ -141,20 +132,6 @@ class ShadRadioGroupState<T> extends State<ShadRadioGroup<T>> {
}
}

class ShadInheritedRadioGroupContainer<T> extends InheritedWidget {
const ShadInheritedRadioGroupContainer({
super.key,
required this.data,
required super.child,
});

final ShadRadioGroupState<T> data;

@override
bool updateShouldNotify(ShadInheritedRadioGroupContainer<T> oldWidget) =>
true;
}

class ShadRadio<T> extends StatefulWidget {
const ShadRadio({
super.key,
Expand Down Expand Up @@ -233,12 +210,8 @@ class _ShadRadioState<T> extends State<ShadRadio<T>> {
@override
Widget build(BuildContext context) {
assert(debugCheckHasShadTheme(context));
assert(
ShadRadioGroup.maybeOf<T>(context) != null,
'Cannot find ShadRadioGroup InheritedWidget',
);
final theme = ShadTheme.of(context);
final inheritedRadioGroup = ShadRadioGroup.of<T>(context);
final inheritedRadioGroup = context.watch<ShadRadioGroupState<dynamic>>();

void onTap() {
inheritedRadioGroup.select(widget.value);
Expand Down
48 changes: 6 additions & 42 deletions lib/src/components/select.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> = Widget Function(
BuildContext context,
Expand Down Expand Up @@ -450,27 +451,6 @@ class ShadSelect<T> extends StatefulWidget {
/// {@endtemplate}
final bool? shrinkWrap;

static ShadSelectState<T> of<T>(BuildContext context, {bool listen = true}) {
return maybeOf<T>(context, listen: listen)!;
}

static ShadSelectState<T>? maybeOf<T>(
BuildContext context, {
bool listen = true,
}) {
if (listen) {
return context
.dependOnInheritedWidgetOfExactType<ShadInheritedSelectContainer<T>>()
?.data;
}
final provider = context
.getElementForInheritedWidgetOfExactType<
ShadInheritedSelectContainer<T>>()
?.widget;

return (provider as ShadInheritedSelectContainer<T>?)?.data;
}

@override
ShadSelectState<T> createState() => ShadSelectState();
}
Expand Down Expand Up @@ -867,8 +847,9 @@ class ShadSelectState<T> extends State<ShadSelect<T>> {
)
: null;

return ShadInheritedSelectContainer(
data: this,
return ShadProvider(
data: this as ShadSelectState<dynamic>,
notifyUpdate: (_) => true,
child: ShadPopover(
groupId: widget.groupId,
padding: EdgeInsets.zero,
Expand Down Expand Up @@ -948,19 +929,6 @@ class ShadSelectState<T> extends State<ShadSelect<T>> {
}
}

class ShadInheritedSelectContainer<T> extends InheritedWidget {
const ShadInheritedSelectContainer({
super.key,
required this.data,
required super.child,
});

final ShadSelectState<T> data;

@override
bool updateShouldNotify(ShadInheritedSelectContainer<T> oldWidget) => true;
}

class ShadOption<T> extends StatefulWidget {
const ShadOption({
super.key,
Expand Down Expand Up @@ -1005,7 +973,7 @@ class _ShadOptionState<T> extends State<ShadOption<T>> {
super.initState();
focusNode.addListener(onFocusChange);

final inherited = ShadSelect.of<T>(context, listen: false);
final inherited = context.read<ShadSelectState<dynamic>>();
final selected = inherited.selectedValues.contains(widget.value);
if (selected) focusNode.requestFocus();
}
Expand All @@ -1026,11 +994,7 @@ class _ShadOptionState<T> extends State<ShadOption<T>> {
@override
Widget build(BuildContext context) {
final theme = ShadTheme.of(context);
assert(
ShadSelect.maybeOf<T>(context) != null,
'Cannot find ShadSelect InheritedWidget',
);
final inheritedSelect = ShadSelect.of<T>(context);
final inheritedSelect = context.watch<ShadSelectState<dynamic>>();
final selected = inheritedSelect.selectedValues.contains(widget.value);

if (selected) {
Expand Down
37 changes: 5 additions & 32 deletions lib/src/components/tabs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> extends InheritedWidget {
const ShadTabsInheritedWidget({
super.key,
required this.data,
required super.child,
});

final ShadTabsState<T> data;

static ShadTabsState<T> of<T>(BuildContext context) {
final provider = maybeOf<T>(context);
if (provider == null) {
throw FlutterError('No ShadTabs widget found in context');
}
return provider;
}

static ShadTabsState<T>? maybeOf<T>(BuildContext context) {
return context
.dependOnInheritedWidgetOfExactType<ShadTabsInheritedWidget<T>>()
?.data;
}

@override
bool updateShouldNotify(covariant ShadTabsInheritedWidget<T> oldWidget) {
return true;
}
}

class ShadTabsController<T> extends ChangeNotifier {
ShadTabsController({required T value}) : selected = value;

Expand Down Expand Up @@ -323,8 +295,9 @@ class ShadTabsState<T> extends State<ShadTabs<T>> with RestorationMixin {
tabBar = Padding(padding: effectivePadding, child: tabBar);
}

return ShadTabsInheritedWidget<T>(
data: this,
return ShadProvider(
data: this as ShadTabsState<dynamic>,
notifyUpdate: (_) => true,
child: ListenableBuilder(
listenable: controller,
builder: (context, _) {
Expand Down Expand Up @@ -620,7 +593,7 @@ class _ShadTabState<T> extends State<ShadTab<T>> {
@override
Widget build(BuildContext context) {
final theme = ShadTheme.of(context);
final inherited = ShadTabsInheritedWidget.of<T>(context);
final inherited = context.watch<ShadTabsState<dynamic>>();

final tabsTheme = theme.tabsTheme;

Expand Down
8 changes: 7 additions & 1 deletion lib/src/components/toast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ class ShadToaster extends StatefulWidget {
State<ShadToaster> 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) {
Expand Down

0 comments on commit 17722c5

Please sign in to comment.