Auto-indexing service and GraphQL API for AT Protocol Records
at main 100 lines 2.8 kB view raw
1import lustre/attribute 2import lustre/element.{type Element} 3import lustre/element/html 4import lustre/event 5 6/// Standard input styling used throughout the app 7const input_classes = "font-mono px-4 py-2 text-sm text-zinc-300 bg-zinc-900 border border-zinc-800 rounded focus:outline-none focus:border-zinc-700 w-full" 8 9/// Standard label styling 10const label_classes = "block text-sm text-zinc-400 mb-2" 11 12/// Render a text input field with label 13pub fn text_input( 14 label label: String, 15 name name: String, 16 value value: String, 17 placeholder placeholder: String, 18 on_input on_input: fn(String) -> msg, 19) -> Element(msg) { 20 html.div([attribute.class("mb-4")], [ 21 html.label([attribute.class(label_classes), attribute.for(name)], [ 22 element.text(label), 23 ]), 24 html.input([ 25 attribute.type_("text"), 26 attribute.name(name), 27 attribute.id(name), 28 attribute.value(value), 29 attribute.placeholder(placeholder), 30 attribute.class(input_classes), 31 event.on_input(on_input), 32 ]), 33 ]) 34} 35 36/// Render a text input field with label for forms (no event handler) 37pub fn form_text_input( 38 label label: String, 39 name name: String, 40 value value: String, 41 placeholder placeholder: String, 42 required required: Bool, 43) -> Element(msg) { 44 let required_attr = case required { 45 True -> [attribute.attribute("required", "")] 46 False -> [] 47 } 48 49 html.div([attribute.class("mb-4")], [ 50 html.label([attribute.class(label_classes), attribute.for(name)], [ 51 element.text(label), 52 case required { 53 True -> 54 html.span([attribute.class("text-red-500 ml-1")], [element.text("*")]) 55 False -> element.none() 56 }, 57 ]), 58 html.input([ 59 attribute.type_("text"), 60 attribute.name(name), 61 attribute.id(name), 62 attribute.value(value), 63 attribute.placeholder(placeholder), 64 attribute.class(input_classes), 65 ..required_attr 66 ]), 67 ]) 68} 69 70/// Render a file input field with label for forms 71pub fn form_file_input( 72 label label: String, 73 name name: String, 74 accept accept: String, 75 required required: Bool, 76) -> Element(msg) { 77 let required_attr = case required { 78 True -> [attribute.attribute("required", "")] 79 False -> [] 80 } 81 82 html.div([attribute.class("mb-4")], [ 83 html.label([attribute.class(label_classes), attribute.for(name)], [ 84 element.text(label), 85 case required { 86 True -> 87 html.span([attribute.class("text-red-500 ml-1")], [element.text("*")]) 88 False -> element.none() 89 }, 90 ]), 91 html.input([ 92 attribute.type_("file"), 93 attribute.name(name), 94 attribute.id(name), 95 attribute.attribute("accept", accept), 96 attribute.class(input_classes), 97 ..required_attr 98 ]), 99 ]) 100}