💄 Refactor usability of input fields

This commit is contained in:
Andrés Moya 2020-06-17 12:49:00 +02:00 committed by Andrey Antukh
parent 8c49d11026
commit b7bf7c8baf
2 changed files with 104 additions and 86 deletions

View file

@ -86,21 +86,18 @@ textarea {
.custom-input { .custom-input {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
position: relative;
label {
font-size: $fs10;
color: $color-gray-30;
}
input { input {
background-color: $color-white;
border-radius: 2px;
border: 1px solid $color-gray-20;
color: $color-gray-60; color: $color-gray-60;
font-size: $fs12; font-size: $fs12;
height: 40px;
margin: 0;
padding: 15px 15px 0 15px;
width: 100%; width: 100%;
border: 0px;
padding: 0px;
margin: 0px;
background-color: transparent;
} }
// Makes the background for autocomplete white // Makes the background for autocomplete white
@ -111,38 +108,77 @@ textarea {
-webkit-box-shadow: 0 0 0 30px $color-white inset !important; -webkit-box-shadow: 0 0 0 30px $color-white inset !important;
} }
.input-container { label {
display: flex; font-size: $fs10;
flex-direction: row; color: $color-gray-30;
position: absolute;
left: 15px;
top: 6px;
}
background-color: $color-white; &.invalid {
border-radius: 2px; input {
border: 1px solid $color-gray-20;
height: 40px;
padding-left: 15px;
padding-right: 15px;
&.invalid {
border-color: $color-danger; border-color: $color-danger;
label {
color: $color-danger;
}
} }
label {
color: $color-danger;
}
}
&.valid { &.valid {
input {
border-color: $color-success; border-color: $color-success;
} }
}
&.focus { &.focus {
input {
border-color: $color-gray-60; border-color: $color-gray-60;
} }
}
&.disabled { &.disabled {
input {
background-color: lighten($color-gray-10, 5%); background-color: lighten($color-gray-10, 5%);
user-select: none; user-select: none;
} }
} }
&.empty {
input {
padding-top: 0;
}
label {
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
width: 1px;
}
}
&.with-icon {
input {
padding-right: 50px;
}
}
.help-icon {
position: absolute;
right: 15px;
top: 12px;
display: flex;
justify-content: center;
align-items: center;
svg {
fill: $color-gray-30;
width: 15px;
height: 15px;
}
}
.hint { .hint {
padding: 4px; padding: 4px;
font-size: $fs10; font-size: $fs10;
@ -153,28 +189,6 @@ textarea {
padding: 4px; padding: 4px;
font-size: $fs10; font-size: $fs10;
} }
.main-content {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: center;
padding-top: 6px;
padding-bottom: 6px;
}
.help-icon {
display: flex;
justify-content: center;
align-items: center;
padding-left: 10px;
svg {
fill: $color-gray-30;
width: 15px;
height: 15px;
}
}
} }
.custom-select { .custom-select {

View file

@ -23,20 +23,36 @@
(mf/defc input (mf/defc input
[{:keys [type label help-icon disabled name form hint] :as props}] [{:keys [type label help-icon disabled name form hint] :as props}]
(let [form (mf/use-ctx form-ctx) (let [form (mf/use-ctx form-ctx)
type' (mf/use-state type) type' (mf/use-state type)
focus? (mf/use-state false) focus? (mf/use-state false)
locale (mf/deref i18n/locale) locale (mf/deref i18n/locale)
touched? (get-in form [:touched name]) touched? (get-in form [:touched name])
error (get-in form [:errors name]) error (get-in form [:errors name])
value (get-in form [:data name] "")
help-icon' (cond
(and (= type "password")
(= @type' "password"))
i/eye
(and (= type "password")
(= @type' "text"))
i/eye-closed
:else
help-icon)
klass (dom/classnames klass (dom/classnames
:focus @focus? :focus @focus?
:valid (and touched? (not error)) :valid (and touched? (not error))
:invalid (and touched? error) :invalid (and touched? error)
:disabled disabled) :disabled disabled
:empty (str/empty? value)
:with-icon (not (nil? help-icon')))
swap-text-password swap-text-password
(fn [] (fn []
@ -54,8 +70,6 @@
(when-not (get-in form [:touched name]) (when-not (get-in form [:touched name])
(swap! form assoc-in [:touched name] true))) (swap! form assoc-in [:touched name] true)))
value (get-in form [:data name] "")
props (-> props props (-> props
(dissoc :help-icon :form) (dissoc :help-icon :form)
(assoc :value value (assoc :value value
@ -67,32 +81,22 @@
(obj/clj->props))] (obj/clj->props))]
[:div.field.custom-input [:div.field.custom-input
[:div.input-container {:class klass} {:class klass}
[:div.main-content [:*
(when-not (str/empty? value) [:label label]
[:label label]) [:> :input props]
[:> :input props]] (when help-icon'
[:div.help-icon [:div.help-icon
{:style {:cursor "pointer"} {:style {:cursor "pointer"}
:on-click (when (= "password" type) :on-click (when (= "password" type)
swap-text-password)} swap-text-password)}
(cond help-icon'])
(and (= type "password") (cond
(= @type' "password")) (and touched? (:message error))
i/eye [:span.error (t locale (:message error))]
(and (= type "password") (string? hint)
(= @type' "text")) [:span.hint hint])]]))
i/eye-closed
:else
help-icon)]]
(cond
(and touched? (:message error))
[:span.error (t locale (:message error))]
(string? hint)
[:span.hint hint])]))
(mf/defc select (mf/defc select
[{:keys [options label name form default] [{:keys [options label name form default]