mirror of
https://github.com/penpot/penpot.git
synced 2025-02-13 10:38:13 -05:00
♻️ Refactor fm/submit-button component
This commit is contained in:
parent
9b9c5822d1
commit
98091057f9
15 changed files with 114 additions and 69 deletions
|
@ -177,12 +177,12 @@
|
|||
[:div.buttons-stack
|
||||
(when (or (contains? cf/flags :login)
|
||||
(contains? cf/flags :login-with-password))
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.login-submit")
|
||||
:data-test "login-submit"}])
|
||||
|
||||
(when (contains? cf/flags :login-with-ldap)
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.login-with-ldap-submit")
|
||||
:on-click on-submit-ldap}])]]]))
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
:name :password-2
|
||||
:label (tr "auth.confirm-password")}]]
|
||||
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.recovery-submit")}]]))
|
||||
|
||||
;; --- Recovery Request Page
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
(mf/defc recovery-form
|
||||
[{:keys [on-success-callback] :as props}]
|
||||
(let [form (fm/use-form :spec ::recovery-request-form
|
||||
(let [form (fm/use-form :spec ::recovery-request-form
|
||||
:validators [handle-error-messages]
|
||||
:initial {})
|
||||
submitted (mf/use-state false)
|
||||
|
@ -82,7 +82,7 @@
|
|||
:help-icon i/at
|
||||
:type "text"}]]
|
||||
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.recovery-request-submit")
|
||||
:data-test "recovery-resquest-submit"}]]))
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
:label (tr "auth.password")
|
||||
:type "password"}]]
|
||||
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.register-submit")
|
||||
:disabled @submitted?
|
||||
:data-test "register-form-submit"}]]))
|
||||
|
@ -259,7 +259,7 @@
|
|||
[:span ",\u00A0"]
|
||||
[:a {:href "https://penpot.app/privacy" :target "_blank"} (tr "auth.privacy-policy")]]])
|
||||
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "auth.register-submit")
|
||||
:disabled @submitted?}]]))
|
||||
|
||||
|
|
|
@ -236,56 +236,98 @@
|
|||
i/arrow-slide]]]))
|
||||
|
||||
(mf/defc radio-buttons
|
||||
[{:keys [name options form trim on-change-value] :as props}]
|
||||
(let [form (or form (mf/use-ctx form-ctx))
|
||||
value (get-in @form [:data name] "")
|
||||
on-change-value (or on-change-value (constantly nil))
|
||||
on-change (fn [event]
|
||||
(let [value (-> event dom/get-target dom/get-value)]
|
||||
(swap! form assoc-in [:touched name] true)
|
||||
(fm/on-input-change form name value trim)
|
||||
(on-change-value name value)))]
|
||||
[:div.custom-radio
|
||||
(for [item options]
|
||||
(let [id (str/ffmt "%-%" name (:value item))
|
||||
image (:image item)]
|
||||
[:div.input-radio {:key id :class (when image "with-image")}
|
||||
[:input {:on-change on-change
|
||||
:type "radio"
|
||||
:id id
|
||||
:name name
|
||||
:value (:value item)
|
||||
:checked (= value (:value item))}]
|
||||
[:label {:for id
|
||||
:style {:background-image (when image (str/ffmt "url(%)" image))}
|
||||
:class (when image "with-image")}
|
||||
(:label item)]]))]))
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [form (or (unchecked-get props "form")
|
||||
(mf/use-ctx form-ctx))
|
||||
name (unchecked-get props "name")
|
||||
|
||||
(mf/defc submit-button
|
||||
[{:keys [label form on-click disabled data-test] :as props}]
|
||||
(let [form (or form (mf/use-ctx form-ctx))]
|
||||
[:input.btn-primary.btn-large
|
||||
{:name "submit"
|
||||
:class (when (or (not (:valid @form)) (true? disabled)) "btn-disabled")
|
||||
:disabled (or (not (:valid @form)) (true? disabled))
|
||||
:tab-index "0"
|
||||
:on-click on-click
|
||||
:on-key-down (fn [event]
|
||||
(when (kbd/enter? event)
|
||||
(on-click)))
|
||||
:value label
|
||||
:data-test data-test
|
||||
:type "submit"}]))
|
||||
current-value (or (dm/get-in @form [:data name] "")
|
||||
(unchecked-get props "value"))
|
||||
on-change (unchecked-get props "on-change")
|
||||
options (unchecked-get props "options")
|
||||
trim? (unchecked-get props "trim")
|
||||
encode-fn (d/nilv (unchecked-get props "encode-fn") identity)
|
||||
decode-fn (d/nilv (unchecked-get props "decode-fn") identity)
|
||||
|
||||
on-change'
|
||||
(mf/use-fn
|
||||
(mf/deps on-change form name)
|
||||
(fn [event]
|
||||
(let [value (-> event dom/get-target dom/get-value decode-fn)]
|
||||
(when (some? form)
|
||||
(swap! form assoc-in [:touched name] true)
|
||||
(fm/on-input-change form name value trim?))
|
||||
|
||||
(when (fn? on-change)
|
||||
(on-change name value)))))]
|
||||
|
||||
[:div.custom-radio
|
||||
(for [{:keys [image value label]} options]
|
||||
(let [image? (some? image)
|
||||
value' (encode-fn value)
|
||||
key (str/ffmt "%-%" name value')]
|
||||
[:div.input-radio {:key key :class (when image? "with-image")}
|
||||
[:input {:on-change on-change'
|
||||
:type "radio"
|
||||
:id key
|
||||
:name name
|
||||
:value value'
|
||||
:checked (= value current-value)}]
|
||||
[:label {:for key
|
||||
:style {:background-image (when image? (str/ffmt "url(%)" image))}
|
||||
:class (when image? "with-image")}
|
||||
label]]))]))
|
||||
|
||||
(mf/defc submit-button*
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [form (or (unchecked-get props "form")
|
||||
(mf/use-ctx form-ctx))
|
||||
|
||||
label (unchecked-get props "label")
|
||||
on-click (unchecked-get props "onClick")
|
||||
children (unchecked-get props "children")
|
||||
|
||||
class (d/nilv (unchecked-get props "className") "btn-primary btn-large")
|
||||
name (d/nilv (unchecked-get props "name") "submit")
|
||||
|
||||
disabled? (or (and (some? form) (not (:valid @form)))
|
||||
(true? (unchecked-get props "disabled")))
|
||||
|
||||
klass (dm/str class " " (if disabled? "btn-disabled" ""))
|
||||
|
||||
on-key-down
|
||||
(mf/use-fn
|
||||
(mf/deps on-click)
|
||||
(fn [event]
|
||||
(when (and (kbd/enter? event) (fn? on-click))
|
||||
(on-click event))))
|
||||
|
||||
props (-> (obj/clone props)
|
||||
(obj/unset! "children")
|
||||
(obj/set! "disabled" disabled?)
|
||||
(obj/set! "onKeyDown" on-key-down)
|
||||
(obj/set! "name" name)
|
||||
(obj/set! "label" mf/undefined)
|
||||
(obj/set! "className" klass)
|
||||
(obj/set! "type" "submit"))]
|
||||
|
||||
[:> "button" props
|
||||
(if (some? children)
|
||||
children
|
||||
[:span label])]))
|
||||
|
||||
(mf/defc form
|
||||
[{:keys [on-submit form children class] :as props}]
|
||||
(let [on-submit (or on-submit (constantly nil))]
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [on-submit form children class]}]
|
||||
(let [on-submit' (mf/use-fn
|
||||
(fn [event]
|
||||
(dom/prevent-default event)
|
||||
(when (fn? on-submit)
|
||||
(on-submit form event))))]
|
||||
[:& (mf/provider form-ctx) {:value form}
|
||||
[:form {:class class
|
||||
:on-submit (fn [event]
|
||||
(dom/prevent-default event)
|
||||
(on-submit form event))}
|
||||
children]]))
|
||||
[:form {:class class :on-submit on-submit'} children]]))
|
||||
|
||||
(defn- conj-dedup
|
||||
"A helper that adds item into a vector and removes possible
|
||||
|
|
|
@ -185,9 +185,10 @@
|
|||
:on-submit on-submit}]]
|
||||
|
||||
[:div.action-buttons
|
||||
[:& fm/submit-button {:label (tr "modals.invite-member-confirm.accept")
|
||||
:disabled (and (boolean (some current-data-emails current-members-emails))
|
||||
(empty? (remove current-members-emails current-data-emails)))}]]]]))
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "modals.invite-member-confirm.accept")
|
||||
:disabled (and (boolean (some current-data-emails current-members-emails))
|
||||
(empty? (remove current-members-emails current-data-emails)))}]]]]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; MEMBERS SECTION
|
||||
|
@ -814,7 +815,7 @@
|
|||
{:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click #(modal/hide!)}]
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (if webhook
|
||||
(tr "modals.edit-webhook.submit-label")
|
||||
(tr "modals.create-webhook.submit-label"))}]]]]]]))
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (if team
|
||||
(tr "labels.update-team")
|
||||
(tr "labels.create-team"))}]]]]]]))
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
children
|
||||
[:div.buttons
|
||||
[:div.step-next
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (if (< step 4) (tr "questions.next") (tr "questions.start"))
|
||||
:class "step-next"}]]
|
||||
|
||||
|
@ -114,7 +114,7 @@
|
|||
{:label (tr "questions.never-used-a-tool") :value "never-used-a-tool" :image "images/form/never-used.png"}
|
||||
{:label (tr "questions.other") :value "other"}]
|
||||
:name :experience-design-tool
|
||||
:on-change-value on-design-tool-change}]
|
||||
:on-change on-design-tool-change}]
|
||||
[:div.other
|
||||
[:label (tr "questions.other")]
|
||||
[:& fm/input {:name :experience-design-tool-other :label (tr "questions.other") :disabled (not= experience-design-tool "other")}]]]))
|
||||
|
@ -152,7 +152,7 @@
|
|||
{:label (tr "questions.student-teacher") :value "student-teacher"}
|
||||
{:label (tr "questions.other") :value "other"}]
|
||||
:name :role
|
||||
:on-change-value on-role-change}]
|
||||
:on-change on-role-change}]
|
||||
[:div.other
|
||||
[:label (tr "questions.other")]
|
||||
[:& fm/input {:name :role-other :label (tr "questions.other") :disabled (not= role "other")}]]
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
:name :name
|
||||
:label (tr "onboarding.choice.team-up.create-team-placeholder")}]
|
||||
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "labels.continue")}]]
|
||||
|
||||
[:button.skip-action {:on-click on-skip} (tr "onboarding.choice.team-up.create-later")]]
|
||||
|
@ -199,8 +199,9 @@
|
|||
:name name
|
||||
:step 2}))}
|
||||
(tr "labels.back")]
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "onboarding.choice.team-up.invite-members-submit")}]]
|
||||
|
||||
[:div.skip-action
|
||||
{:on-click on-skip}
|
||||
[:div.action (tr "onboarding.choice.team-up.invite-members-skip")]]]]
|
||||
|
|
|
@ -166,7 +166,7 @@
|
|||
{:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click #(modal/hide!)}]
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "modals.create-access-token.submit-label")}]])]]]]]))
|
||||
|
||||
(mf/defc access-tokens-hero
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons {:data-test "change-email-submit"}
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "modals.change-email.submit")}]]]]]]))
|
||||
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
:name :content
|
||||
:rows 5}]]
|
||||
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (if @loading (tr "labels.sending") (tr "labels.send"))
|
||||
:disabled @loading}]
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
(st/emit! (du/update-profile (with-meta data mdata)))))
|
||||
|
||||
(mf/defc options-form
|
||||
{::mf/wrap-props false}
|
||||
[]
|
||||
(let [profile (mf/deref refs/profile)
|
||||
initial (mf/with-memo [profile]
|
||||
|
@ -66,7 +67,7 @@
|
|||
:options [{:label "Penpot Dark (default)" :value "default"}
|
||||
{:label "Penpot Light" :value "light"}]
|
||||
:data-test "setting-theme"}]])
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "dashboard.update-settings")
|
||||
:data-test "submit-lang-change"}]]))
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
:name :password-2
|
||||
:label (t locale "labels.confirm-password")}]]
|
||||
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (t locale "dashboard.update-settings")
|
||||
:data-test "submit-password"}]]))
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
[:a {:on-click #(modal/show! :change-email {})}
|
||||
(tr "dashboard.change-email")]]]]
|
||||
|
||||
[:& fm/submit-button
|
||||
[:> fm/submit-button*
|
||||
{:label (tr "dashboard.save-settings")
|
||||
:disabled (empty? (:touched @form))}]
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue