From 1bae5014273eb973de2eafa9fe5212ca1ca2c5a5 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 13 Oct 2026 18:49:10 +0000 Subject: [PATCH] :bug: Stop tooltip-class leaking onto numeric input element Consume the custom tooltip class in the numeric input and token field components so it styles the token button tooltip instead of leaking onto the inner DOM input and triggering the React unknown-prop warning on layout-item size inputs. Closes #12311 AI-assisted-by: muse-spark-1.3-contributor --- .../main/ui/ds/controls/numeric_input.cljs | 7 +++- .../ui/ds/controls/utilities/token_field.cljs | 6 ++- .../ui/ds_controls_numeric_input_test.cljs | 38 ++++++++++++++++++- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/main/ui/ds/controls/numeric_input.cljs b/frontend/src/app/main/ui/ds/controls/numeric_input.cljs index 7595f8873c..9811013a39 100644 --- a/frontend/src/app/main/ui/ds/controls/numeric_input.cljs +++ b/frontend/src/app/main/ui/ds/controls/numeric_input.cljs @@ -167,6 +167,8 @@ [:on-focus {:optional true} fn?] [:on-detach {:optional true} fn?] [:property {:optional true} :string] + [:tooltip-class {:optional true} + [:maybe :string]] [:tooltip-placement {:optional true} [:maybe [:enum "top" "bottom" "left" "right" "top-right" "bottom-right" "bottom-left" "top-left"]]] [:align {:optional true} [:maybe [:enum :left :right]]]]) @@ -182,7 +184,7 @@ on-change on-change-start on-change-end on-blur on-focus on-detach property align ref name - tooltip-placement text-icon] + tooltip-class tooltip-placement text-icon] :rest props}] (let [;; NOTE: we use mfu/bean here for transparently handle @@ -760,7 +762,7 @@ (when (some? tokens) (mf/html [:> icon-button* {:variant "ghost" :icon i/tokens - :tooltip-class (stl/css :button-tooltip) + :tooltip-class (or tooltip-class (stl/css :button-tooltip)) :class (stl/css :invisible-button) :aria-label token-tooltip :ref open-dropdown-ref @@ -794,6 +796,7 @@ :class inner-class :property property :is-open is-open + :tooltip-class tooltip-class :tooltip-placement tooltip-placement :slot-start (when (or icon text-icon) (mf/html diff --git a/frontend/src/app/main/ui/ds/controls/utilities/token_field.cljs b/frontend/src/app/main/ui/ds/controls/utilities/token_field.cljs index befe593d16..c85735685f 100644 --- a/frontend/src/app/main/ui/ds/controls/utilities/token_field.cljs +++ b/frontend/src/app/main/ui/ds/controls/utilities/token_field.cljs @@ -32,6 +32,8 @@ [:on-token-key-down fn?] [:on-blur {:optional true} fn?] [:on-focus {:optional true} fn?] + [:tooltip-class {:optional true} + [:maybe :string]] [:tooltip-placement {:optional true} [:maybe [:enum "top" "bottom" "left" "right" "top-right" "bottom-right" "bottom-left" "top-left"]]] [:detach-token fn?]]) @@ -39,7 +41,7 @@ (mf/defc token-field* {::mf/schema schema:token-field} [{:keys [id label value slot-start disabled class - on-click on-token-key-down on-blur detach-token tooltip-placement + on-click on-token-key-down on-blur detach-token tooltip-class tooltip-placement token-wrapper-ref token-detach-btn-ref on-focus property is-open token-has-errors]}] (let [set-active? (some? id) @@ -113,7 +115,7 @@ [:> icon-button* {:variant "ghost" :class (stl/css-case :invisible-button true :invisible-btn-dropdown-open is-open) - :tooltip-class (stl/css :button-tooltip) + :tooltip-class (or tooltip-class (stl/css :button-tooltip)) :tooltip-placement tooltip-placement :icon i/broken-link :ref token-detach-btn-ref diff --git a/frontend/test/frontend_tests/ui/ds_controls_numeric_input_test.cljs b/frontend/test/frontend_tests/ui/ds_controls_numeric_input_test.cljs index 9d9a7cd1a3..c0a60be544 100644 --- a/frontend/test/frontend_tests/ui/ds_controls_numeric_input_test.cljs +++ b/frontend/test/frontend_tests/ui/ds_controls_numeric_input_test.cljs @@ -7,7 +7,9 @@ (ns frontend-tests.ui.ds-controls-numeric-input-test (:require [app.common.data :as d] - [app.main.ui.ds.controls.numeric-input :refer [next-focus-index parse-value token-shortcut]] + [app.common.schema :as sm] + [app.main.ui.ds.controls.numeric-input :as numeric-input :refer [next-focus-index parse-value token-shortcut]] + [app.main.ui.ds.controls.utilities.token-field :as token-field] [app.main.ui.formats :as fmt] [cljs.test :as t :include-macros true])) @@ -134,3 +136,37 @@ (t/testing "works with nil focused-id (no current selection)" (t/is (= 0 (next-focus-index sample-options nil :down))))) + +;; Regression pins for the React `tooltipClass` unknown-prop warning: +;; `numeric-input*` receives `:tooltip-class` from callers such as the +;; layout-item menus (via `numeric-input-wrapper*`). The prop must be +;; declared in the schema and destructured by the component, so it never +;; stays in the `:rest` props that are spread onto the inner `input-field*` +;; DOM ``. `:tooltip-placement` already follows this pattern; +;; `:tooltip-class` mirrors it. The same holds for `token-field*`, which +;; forwards the class to its detach-button `icon-button*`. + +(t/deftest test-numeric-input-schema-accepts-tooltip-class + (let [schema @#'numeric-input/schema:numeric-input] + (t/testing "absent tooltip-class stays valid" + (t/is (true? (sm/validate schema {})))) + (t/testing "string tooltip-class is accepted" + (t/is (true? (sm/validate schema {:tooltip-class "my-tooltip"})))) + (t/testing "nil tooltip-class is accepted" + (t/is (true? (sm/validate schema {:tooltip-class nil})))) + (t/testing "non-string tooltip-class is rejected" + (t/is (false? (sm/validate schema {:tooltip-class 42})))))) + +(t/deftest test-token-field-schema-accepts-tooltip-class + (let [schema @#'token-field/schema:token-field + base {:value "10" + :on-token-key-down (fn [_]) + :detach-token (fn [_])}] + (t/testing "absent tooltip-class stays valid" + (t/is (true? (sm/validate schema base)))) + (t/testing "string tooltip-class is accepted" + (t/is (true? (sm/validate schema (assoc base :tooltip-class "my-tooltip"))))) + (t/testing "nil tooltip-class is accepted" + (t/is (true? (sm/validate schema (assoc base :tooltip-class nil))))) + (t/testing "non-string tooltip-class is rejected" + (t/is (false? (sm/validate schema (assoc base :tooltip-class 42)))))))