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

Dialog Bypass on Rapid Increment/Decrement Clicks with Stimulus #144

Open
AdamMusa opened this issue Sep 13, 2024 · 0 comments
Open

Dialog Bypass on Rapid Increment/Decrement Clicks with Stimulus #144

AdamMusa opened this issue Sep 13, 2024 · 0 comments

Comments

@AdamMusa
Copy link

When rapidly clicking the increment or decrement buttons, the dialog intended to appear based on specific countValue conditions (10 or -3) sometimes fails to show as expected.

bug

To Reproduce the Bug

  1. Copy and paste the provided code into your project.
  2. Run the application.
  3. Rapidly click the increment or decrement button to observe the dialog behavior.
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="counter"
export default class extends Controller {
  static targets = ['count','showDialog']
  static values = {count: Number,active: Boolean}
  connect() {
    this.countValue = 0
    this.activeValue = false;
    this.updateCount()
    this.showDialog()

  }

  increment(){
    this.countValue++
    this.updateCount()
    this.showDialog()
  }

  decrement(){
   this.countValue--
   this.updateCount()
   this.showDialog()
  }

  updateCount(){
    this.countTarget.textContent = this.countValue
  }
  showDialog(){
    this.activeValue =  (this.countValue == 10 || this.countValue == -3)
    if(this.activeValue) this.showDialogTarget.classList.remove('hidden')
  }

  showDialog() {
    const shouldShowDialog = (this.countValue === 10 || this.countValue === -3);
    if (shouldShowDialog) {
      this.showDialogTarget.classList.remove('hidden');
      setTimeout(() => {
        this.showDialogTarget.classList.remove('opacity-0', 'pointer-events-none');
        this.showDialogTarget.classList.add('opacity-100');
      }, 10); // Delay to ensure class removal is processed
    } else {
      this.showDialogTarget.classList.remove('opacity-100');
      this.showDialogTarget.classList.add('opacity-0');
      setTimeout(() => {
        this.showDialogTarget.classList.add('hidden');
        this.showDialogTarget.classList.remove('pointer-events-none');
      }, 300); // Duration of the fade-out animation
    }
  }
  closeDialog() {
    this.countValue = 0;
    this.countTarget.textContent = 0;
  
    // Add move-left class for the animation
    this.showDialogTarget.classList.add('move-left');
  
    setTimeout(() => {
      this.showDialogTarget.classList.add('hidden');
      this.showDialogTarget.classList.remove('pointer-events-none');
      // Remove the move-left class to reset for future openings
      this.showDialogTarget.classList.remove('move-left');
    }, 300); // Duration of the animation
  }
  
}

this is my view code

<div data-controller="counter" class="w-full h-full">
  <!-- Increment button with multiple actions -->
  <button data-action="click->counter#increment mouseover->counter#increment">Increment</button>
  
  <!-- Display count value -->
  <p data-counter-target="count"></p>
  
  <!-- Decrement button -->
  <button data-action="click->counter#decrement">Decrement</button>
  
  <!-- Dialog element with data-controller-target -->
 <!-- Dialog element with data-controller-target -->
  <div data-counter-target="showDialog" class="fixed inset-0 flex items-center justify-center z-50 opacity-0 pointer-events-none transition-opacity duration-300 ease-out hidden">
    <div class="bg-black bg-opacity-70 p-6 shadow-lg w-full h-full flex items-center justify-center">
      <div class="bg-white p-6 rounded-lg max-w-4xl w-full">
        <h2 class="text-black text-xl font-semibold mb-4">Dialog Title</h2>
        <p class="text-black mb-4">This is the content of the dialog card. You can add more text or HTML here.</p>
        <button data-action="click->counter#closeDialog" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">
          Close
        </button>
      </div>
    </div>
  </div>
</div>

<div data-controller="home">
  <div data-home-target="change">
  </div>
  <h1 class="font-bold text-4xl" data-action="click->home#open">Home#index</h1>
  <p  data-action="click->home#replace">Find me in app/views/home/index.html.erb</p>
</div>

Expected Behavior
The dialog should consistently appear when countValue is 10 or -3 in my case, and disappear otherwise, regardless of how quickly the increment or decrement buttons are clicked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant