Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ShadSlider onChanged callback getting called on controller update #201

Closed
helightdev opened this issue Nov 27, 2024 · 5 comments · Fixed by #202
Closed

ShadSlider onChanged callback getting called on controller update #201

helightdev opened this issue Nov 27, 2024 · 5 comments · Fixed by #202
Assignees
Labels
bug Something isn't working

Comments

@helightdev
Copy link
Contributor

Steps to reproduce

  1. Create a stateful widget that contains a ShadSliderController and a ShadSlider
  2. The widget must have some mechanism to manually update the controller
  3. Add debug statements to a controller listener and the onChanged event

Expected results

onChanged should only trigger if the user actually modified the controller using the slider. Not every time the controller gets updated.

Actual results

Every time the controller updates it's value, the ShadSlider will also trigger onChanged

shadcn_ui version

0.15.4

Platform

MacOS, Windows, Linux, Android, iOS, Web

Code sample

Screenshots or Video

No response

Logs

No response

Flutter Doctor output

[!] Flutter (Channel stable, 3.24.4, on Microsoft Windows [Version 10.0.22631.4460], locale en-US)
! The flutter binary is not on your path. Consider adding D:\Tools\flutter-sdk-windows\bin to your path.
! The dart binary is not on your path. Consider adding D:\Tools\flutter-sdk-windows\bin to your path.
[√] Windows Version (Installed version of Windows is version 10 or higher)
[!] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
X cmdline-tools component is missing
Run path/to/sdkmanager --install "cmdline-tools;latest"
See https://developer.android.com/studio/command-line for more details.
X Android license status unknown.
Run flutter doctor --android-licenses to accept the SDK licenses.
See https://flutter.dev/to/windows-android-setup for more details.
[√] Chrome - develop for the web
[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.9.6)
[√] Android Studio (version 2024.2)
[√] IntelliJ IDEA Ultimate Edition (version 2024.2)
[√] VS Code (version 1.92.2)
[√] Connected device (3 available)
[√] Network resources

@helightdev helightdev added bug Something isn't working triage Issues that need assessment and prioritization labels Nov 27, 2024
@helightdev
Copy link
Contributor Author

I'm gonna submit a pr shortly to fix this

@nank1ro
Copy link
Owner

nank1ro commented Nov 27, 2024

onChanged and controller are not supposed to be used together.
If you don't pass a controller you're supposed to use onChanged.
If you pass a controller you're supposed to use it to get the value.

This is the same behaviour used by Material widgets.
But I'm open to understand why you think this different behaviour gives more value.

@helightdev
Copy link
Contributor Author

Basically all material widgets I have ever worked with have the same behavior I am expecting. When you supply a TextField with a TextEditingController, you can still listen for change events using the widget. The main use case for this is synchronizing a controller to another value stream and using the onChanged event push notifications back to the source of the value stream.

Given - You can also do this using multiple addListeners, I still preferred this approach though and I can't think of a material widget with which this didn't work.

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorSchemeSeed: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({
    super.key,
    required this.title,
  });

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final TextEditingController controller = TextEditingController(text: "");

  @override
  void initState() {
    controller.addListener(() {
      print("Value updated!");
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
                controller: controller,
                onChanged: (str) {
                  print("Updated from onChanged!");
                })
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          controller.text = controller.text + "+";
          print("Updated from button!");
        },
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

@helightdev
Copy link
Contributor Author

This is just a small snippet you can run in dart pad to see that this is indeed the default behavior in material

@nank1ro
Copy link
Owner

nank1ro commented Nov 27, 2024

Thanks for the example, I just approved the PR

@nank1ro nank1ro removed the triage Issues that need assessment and prioritization label Nov 27, 2024
@nank1ro nank1ro self-assigned this Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants