@@ -17,6 +17,7 @@ defmodule LivebookWeb.FormComponents do
1717 attr :help , :string , default: nil
1818 attr :type , :string , default: "text"
1919 attr :class , :string , default: nil
20+ attr :outer_prefix , :string , default: nil
2021
2122 attr :rest , :global , include: ~w( autocomplete readonly disabled step min max)
2223
@@ -25,30 +26,80 @@ defmodule LivebookWeb.FormComponents do
2526
2627 ~H"""
2728 < . field_wrapper id = { @ id } name = { @ name } label = { @ label } errors = { @ errors } help = { @ help } >
28- < input
29- type = { @ type }
30- name = { @ name }
31- id = { @ id || @ name }
32- value = { Phoenix.HTML.Form . normalize_value ( "text" , @ value ) }
33- class = { [ input_classes ( @ errors ) , @ class ] }
34- { @ rest }
35- />
29+ <%= if @ outer_prefix do %>
30+ < div class = { outer_prefixed_input_wrapper_classes ( @ errors ) } >
31+ < span class = "inline-flex items-center rounded-l-lg bg-gray-100 px-3 text-sm text-gray-400 opacity-70 border-r border-gray-200 " >
32+ { @ outer_prefix }
33+ </ span >
34+
35+ < input
36+ type = { @ type }
37+ name = { @ name }
38+ id = { @ id || @ name }
39+ value = { Phoenix.HTML.Form . normalize_value ( "text" , @ value ) }
40+ class = { [
41+ outer_prefixed_input_classes ( @ errors ) ,
42+ @ class
43+ ] }
44+ { @ rest }
45+ />
46+ </ div >
47+ <% else %>
48+ < input
49+ type = { @ type }
50+ name = { @ name }
51+ id = { @ id || @ name }
52+ value = { Phoenix.HTML.Form . normalize_value ( "text" , @ value ) }
53+ class = { [ input_classes ( @ errors ) , @ class ] }
54+ { @ rest }
55+ />
56+ <% end %>
3657 </ . field_wrapper >
3758 """
3859 end
3960
40- defp input_classes ( errors ) do
61+ defp outer_prefixed_input_wrapper_classes ( errors ) do
4162 [
42- "w-full px-3 py-2 text-sm font-normal border rounded-lg placeholder-gray-400 disabled:opacity-70 disabled:cursor-not-allowed focus: border-blue-600 focus-visible:outline-none " ,
63+ "relative flex items-stretch rounded-lg border focus-within: border-blue-600" ,
4364 if errors == [ ] do
44- "bg-gray-50 border-gray-200 text-gray-600 "
65+ "border-gray-200"
4566 else
46- "bg-red-50 border-red-600 text-red-600"
47- end ,
67+ "border-red-600"
68+ end
69+ ]
70+ end
71+
72+ defp input_classes ( errors ) do
73+ [
74+ base_input_classes ( ) ,
75+ "border rounded-lg focus:border-blue-600" ,
76+ error_color_classes ( errors ) ,
77+ if ( errors != [ ] , do: "border-red-600" ) ,
4878 "invalid:bg-red-50 invalid:border-red-600 invalid:text-red-600"
4979 ]
5080 end
5181
82+ defp outer_prefixed_input_classes ( errors ) do
83+ [
84+ base_input_classes ( ) ,
85+ "border-0 rounded-none rounded-r-lg focus:ring-0 focus:outline-none" ,
86+ error_color_classes ( errors ) ,
87+ "invalid:text-red-600"
88+ ]
89+ end
90+
91+ defp base_input_classes do
92+ "w-full px-3 py-2 text-sm font-normal placeholder-gray-400 disabled:opacity-70 disabled:cursor-not-allowed focus-visible:outline-none"
93+ end
94+
95+ defp error_color_classes ( errors ) do
96+ if errors == [ ] do
97+ "bg-gray-50 text-gray-600"
98+ else
99+ "bg-red-50 text-red-600"
100+ end
101+ end
102+
52103 @ doc """
53104 Renders a textarea input with label and error messages.
54105 """
0 commit comments