diff --git a/core/misc/states.js b/core/misc/states.js
index 39cd7b41bb3a5fb119eed3c5fe93e6dcb6c581ac..643a72f146d7124cc04a8d1e955ed42cbd7e17bd 100644
--- a/core/misc/states.js
+++ b/core/misc/states.js
@@ -526,6 +526,10 @@
         // the state.
         return this.val() === '';
       },
+      // Listen to 'change' for number native "spinner" widgets.
+      change() {
+        return this.val() === '';
+      },
     },
 
     checked: {
diff --git a/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php b/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php
index 4f8095739ff2c0e04bdad0b94f6c0ae73be01596..851c55e2fc533deabcc2713ee659c2d202dfce86 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php
@@ -106,6 +106,10 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#empty_value' => '_none',
       '#empty_option' => '- None -',
     ];
+    $form['number_trigger'] = [
+      '#type' => 'number',
+      '#title' => 'Number trigger',
+    ];
 
     // Tested fields.
     // Checkbox trigger.
@@ -374,6 +378,17 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       ],
     ];
 
+    // Number triggers.
+    $form['item_visible_when_number_trigger_filled_by_spinner'] = [
+      '#type' => 'item',
+      '#title' => 'Item visible when number trigger filled by spinner widget',
+      '#states' => [
+        'visible' => [
+          ':input[name="number_trigger"]' => ['filled' => TRUE],
+        ],
+      ],
+    ];
+
     $form['select'] = [
       '#type' => 'select',
       '#title' => 'select 1',
diff --git a/core/tests/Drupal/Nightwatch/Tests/statesTest.js b/core/tests/Drupal/Nightwatch/Tests/statesTest.js
index 2ae6d41de457cbef040f76f01503e5c3ef95aac8..4d48d8d3aac8ae31d02643187fc64d3f50777d7c 100644
--- a/core/tests/Drupal/Nightwatch/Tests/statesTest.js
+++ b/core/tests/Drupal/Nightwatch/Tests/statesTest.js
@@ -21,4 +21,25 @@ module.exports = {
       .waitForElementNotVisible('input[name="textfield"]', 1000)
       .assert.noDeprecationErrors();
   },
+  'Test number trigger with spinner widget': (browser) => {
+    browser
+      .drupalRelativeURL('/form-test/javascript-states-form')
+      .waitForElementVisible('body', 1000)
+      .waitForElementNotVisible(
+        '#edit-item-visible-when-number-trigger-filled-by-spinner',
+        1000,
+      )
+      .execute(() => {
+        // Emulate usage of the spinner browser widget on number inputs
+        // on modern browsers.
+        const numberTrigger = document.getElementById('edit-number-trigger');
+        numberTrigger.value = 1;
+        numberTrigger.dispatchEvent(new Event('change'));
+      });
+
+    browser.waitForElementVisible(
+      '#edit-item-visible-when-number-trigger-filled-by-spinner',
+      1000,
+    );
+  },
 };