onasty/web/src/Components/Form.elm(view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
module Components.Form exposing (ButtonStyle(..), CanBeClicked, InputStyle(..), button, input, submitButton)
import Html as H exposing (Html)
import Html.Attributes as A
import Html.Events as E
-- INPUT
type InputStyle
= Simple
| Complex
{ prefix : String
, helpText : String
}
input :
{ id : String
, field : field
, type_ : String
, value : String
, label : String
, placeholder : String
, required : Bool
, onInput : String -> msg
, style : InputStyle
, error : Maybe String
}
-> Html msg
input opts =
let
style =
case opts.style of
Simple ->
{ prefix = H.text "", help = H.text "" }
Complex complex ->
{ prefix = H.span [ A.class "text-gray-500 text-md whitespace-nowrap" ] [ H.text complex.prefix ]
, help = H.p [ A.class "text-xs text-gray-500 mt-1" ] [ H.text complex.helpText ]
}
error =
case opts.error of
Nothing ->
{ element = H.text "", inputAdditionalClasses = "border-gray-300 focus:ring-black " }
Just err ->
{ element = H.p [ A.class "text-red-600 text-xs mt-1" ] [ H.text err ]
, inputAdditionalClasses = " border-red-400 focus:ring-red-500"
}
in
H.div [ A.class "space-y-2" ]
[ H.label
[ A.for opts.id
, A.class "block text-sm font-medium text-gray-700"
]
[ H.text opts.label ]
, H.div [ A.class "flex items-center" ]
[ style.prefix
, H.input
[ A.class ("w-full px-3 py-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:border-transparent transition-colors" ++ error.inputAdditionalClasses)
, A.type_ opts.type_
, A.value opts.value
, A.id opts.id
, A.placeholder opts.placeholder
, A.required opts.required
, E.onInput opts.onInput
]
[]
]
, error.element
, style.help
]
-- BUTTON
type alias CanBeClicked =
Bool
type ButtonStyle
= Primary CanBeClicked
| Secondary CanBeClicked
| SecondaryDisabled CanBeClicked
| SecondaryDanger
button : { text : String, disabled : Bool, onClick : msg, style : ButtonStyle } -> Html msg
button opts =
H.button
[ A.type_ "button"
, E.onClick opts.onClick
, A.class (buttonStyleToClass opts.style "")
, A.disabled opts.disabled
]
[ H.text opts.text ]
submitButton : { text : String, disabled : Bool, class : String, style : ButtonStyle } -> Html msg
submitButton opts =
H.button
[ A.type_ "submit"
, A.class (buttonStyleToClass opts.style opts.class)
, A.disabled opts.disabled
]
[ H.text opts.text ]
buttonStyleToClass : ButtonStyle -> String -> String
buttonStyleToClass style appendClasses =
case style of
Primary canBeClicked ->
getButtonClasses canBeClicked
appendClasses
"px-6 py-2 bg-gray-300 text-gray-500 rounded-md cursor-not-allowed transition-colors"
"px-6 py-2 bg-black text-white rounded-md hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2 transition-colors"
SecondaryDanger ->
"text-gray-600 hover:text-red-600 transition-colors"
Secondary canBeClicked ->
getButtonClasses canBeClicked
appendClasses
"px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2 transition-colors bg-green-100 border-green-300 text-green-700"
"px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2 transition-colors border-gray-300 text-gray-700 hover:bg-gray-50"
SecondaryDisabled canBeClicked ->
getButtonClasses canBeClicked
appendClasses
"w-full px-4 py-2 rounded-md focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2 transition-colors mt-3 border border-gray-300 text-gray-400 cursor-not-allowed"
"w-full px-4 py-2 rounded-md focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2 transition-colors mt-3 border border-gray-300 text-gray-700 hover:bg-gray-50"
getButtonClasses : Bool -> String -> String -> String -> String
getButtonClasses cond extend whenTrue whenFalse =
let
cls =
if String.isEmpty extend then
""
else
" " ++ extend
in
if cond then
whenTrue ++ cls
else
whenFalse ++ cls
|