forked from
slices.network/quickslice
Auto-indexing service and GraphQL API for AT Protocol Records
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}