🐛 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
This commit is contained in:
Andrey Antukh 2026-10-13 18:49:10 +00:00
parent 57ed11942c
commit 1bae501427
3 changed files with 46 additions and 5 deletions

View File

@ -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

View File

@ -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

View File

@ -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 `<input>`. `: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)))))))