diff --git a/frontend/src/app/main/ui/ds/buttons/button.cljs b/frontend/src/app/main/ui/ds/buttons/button.cljs index cfb30409d..e1c04335e 100644 --- a/frontend/src/app/main/ui/ds/buttons/button.cljs +++ b/frontend/src/app/main/ui/ds/buttons/button.cljs @@ -17,20 +17,24 @@ [:class {:optional true} :string] [:icon {:optional true} [:and :string [:fn #(contains? icon-list %)]]] + [:on-ref {:optional true} fn?] [:variant {:optional true} [:maybe [:enum "primary" "secondary" "ghost" "destructive"]]]]) (mf/defc button* {::mf/props :obj ::mf/schema schema:button} - [{:keys [variant icon children class] :rest props}] + [{:keys [variant icon children class on-ref] :rest props}] (let [variant (or variant "primary") class (dm/str class " " (stl/css-case :button true :button-primary (= variant "primary") :button-secondary (= variant "secondary") :button-ghost (= variant "ghost") :button-destructive (= variant "destructive"))) - props (mf/spread-props props {:class class})] + props (mf/spread-props props {:class class + :ref (fn [node] + (when on-ref + (on-ref node)))})] [:> "button" props (when icon [:> icon* {:id icon :size "m"}]) [:span {:class (stl/css :label-wrapper)} children]])) \ No newline at end of file diff --git a/frontend/src/app/main/ui/workspace/tokens/form.cljs b/frontend/src/app/main/ui/workspace/tokens/form.cljs index bae45a303..ad7024209 100644 --- a/frontend/src/app/main/ui/workspace/tokens/form.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/form.cljs @@ -220,6 +220,12 @@ Token names should only contain letters and digits separated by . characters.")} (-> (ctob/tokens-tree selected-set-tokens) ;; Allow setting editing token to it's own path (d/dissoc-in token-path)))) + cancel-ref (mf/use-ref nil) + + on-cancel-ref + (mf/use-fn + (fn [node] + (mf/set-ref-val! cancel-ref node))) ;; Name touched-name? (mf/use-state false) @@ -233,6 +239,17 @@ Token names should only contain letters and digits separated by . characters.")} :tokens-tree selected-set-tokens-tree})] (m/explain schema (finalize-name value))))) + on-blur-name + (mf/use-fn + (mf/deps cancel-ref) + (fn [e] + (let [node (dom/get-related-target e) + on-cancel-btn (= node (mf/ref-val cancel-ref))] + (when-not on-cancel-btn + (let [value (dom/get-target-val e) + errors (validate-name value)] + (reset! name-errors errors)))))) + on-update-name-debounced (mf/use-fn (uf/debounce (fn [e] @@ -319,6 +336,7 @@ Token names should only contain letters and digits separated by . characters.")} (mf/deps validate-name validate-descripion token resolved-tokens) (fn [e] (dom/prevent-default e) + (mf/set-ref-val! cancel-ref nil) ;; We have to re-validate the current form values before submitting ;; because the validation is asynchronous/debounced ;; and the user might have edited a valid form to make it invalid, @@ -356,6 +374,7 @@ Token names should only contain letters and digits separated by . characters.")} on-cancel (mf/use-fn (fn [e] + (mf/set-ref-val! cancel-ref nil) (dom/prevent-default e) (modal/hide!)))] @@ -376,7 +395,7 @@ Token names should only contain letters and digits separated by . characters.")} :auto-focus true :label (tr "workspace.token.token-name") :default-value @name-ref - :on-blur on-update-name + :on-blur on-blur-name :on-change on-update-name}]) (for [error (->> (:errors @name-errors) @@ -432,6 +451,8 @@ Token names should only contain letters and digits separated by . characters.")} (tr "labels.delete")]) [:> button* {:on-click on-cancel :type "button" + :on-ref on-cancel-ref + :id "token-modal-cancel" :variant "secondary"} (tr "labels.cancel")] [:> button* {:type "submit" diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index 6d67e8232..c9b7b1b35 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -76,7 +76,7 @@ checked? (or all? mixed?)] [:div {:role "checkbox" :aria-checked (dm/str checked) - :tabindex 0 + :tab-index 0 :class (stl/css-case :checkbox-style true :checkbox-checked-style checked?) :on-click on-click} diff --git a/frontend/src/app/util/dom.cljs b/frontend/src/app/util/dom.cljs index 797946bae..e1771a2ec 100644 --- a/frontend/src/app/util/dom.cljs +++ b/frontend/src/app/util/dom.cljs @@ -134,6 +134,12 @@ (when (some? event) (.-target event))) +(defn get-related-target + "Extract the related target from a blur or focus event instance." + [^js event] + (when (some? event) + (.-relatedTarget event))) + (defn select-target "Extract the target from event instance and select it" [^js event]