open Htmlit
(* Component configuration *)
type t = {
classes: Tailwind.t option;
attributes: (string * string) list;
id: string option;
data: (string * string) list;
}
(* Helper function to convert Tailwind classes to Htmlit attributes *)
let classes_attr tailwind_classes =
At.class' (Tailwind.to_string tailwind_classes)
(* Create a component with classes and attributes *)
let make ?classes ?attributes ?id ?data () = {
classes;
attributes = (match attributes with Some a -> a | None -> []);
id;
data = (match data with Some d -> d | None -> []);
}
(* Add classes to a component *)
let add_classes new_classes comp = {
comp with classes = match comp.classes with
| Some existing -> Some (Tailwind.Css.tw [existing; new_classes])
| None -> Some new_classes
}
(* Add attributes to a component *)
let add_attributes new_attrs comp = {
comp with attributes = comp.attributes @ new_attrs
}
(* Convert component to Htmlit attributes *)
let to_htmlit_atts comp =
let class_attrs = match comp.classes with
| Some c -> [classes_attr c]
| None -> []
in
let attr_list = List.map (fun (k, v) -> At.v k v) comp.attributes in
let id_attrs = match comp.id with
| Some i -> [At.id i]
| None -> []
in
let data_attrs = List.map (fun (k, v) -> At.v ("data-" ^ k) v) comp.data in
class_attrs @ attr_list @ id_attrs @ data_attrs
(* Apply component to an Htmlit element *)
let apply _comp element =
(* This is a simplified implementation - in reality we'd need to traverse the element *)
element
(* Create HTML elements with component styling *)
let div comp children =
let attrs = to_htmlit_atts comp in
El.div ~at:attrs children
let span comp children =
let attrs = to_htmlit_atts comp in
El.span ~at:attrs children
let section comp children =
let attrs = to_htmlit_atts comp in
El.section ~at:attrs children
let article comp children =
let attrs = to_htmlit_atts comp in
El.article ~at:attrs children
(* Utility functions for common HTML elements *)
let p ?classes ?attrs children =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let all_attrs = match attrs with
| Some a -> base_attrs @ a
| None -> base_attrs
in
El.p ?at:(if all_attrs = [] then None else Some all_attrs) children
let h1 ?classes ?attrs children =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let all_attrs = match attrs with
| Some a -> base_attrs @ a
| None -> base_attrs
in
El.h1 ?at:(if all_attrs = [] then None else Some all_attrs) children
let h2 ?classes ?attrs children =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let all_attrs = match attrs with
| Some a -> base_attrs @ a
| None -> base_attrs
in
El.h2 ?at:(if all_attrs = [] then None else Some all_attrs) children
let h3 ?classes ?attrs children =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let all_attrs = match attrs with
| Some a -> base_attrs @ a
| None -> base_attrs
in
El.h3 ?at:(if all_attrs = [] then None else Some all_attrs) children
let img ?classes ?attrs ~src ~alt () =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let required_attrs = [At.src src; At.alt alt] in
let all_attrs = match attrs with
| Some a -> base_attrs @ required_attrs @ a
| None -> base_attrs @ required_attrs
in
El.img ~at:all_attrs ()
let a ?classes ?attrs ~href children =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let required_attrs = [At.href href] in
let all_attrs = match attrs with
| Some a -> base_attrs @ required_attrs @ a
| None -> base_attrs @ required_attrs
in
El.a ~at:all_attrs children
let ul ?classes ?attrs children =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let all_attrs = match attrs with
| Some a -> base_attrs @ a
| None -> base_attrs
in
El.ul ?at:(if all_attrs = [] then None else Some all_attrs) children
let ol ?classes ?attrs children =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let all_attrs = match attrs with
| Some a -> base_attrs @ a
| None -> base_attrs
in
El.ol ?at:(if all_attrs = [] then None else Some all_attrs) children
let li ?classes ?attrs children =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let all_attrs = match attrs with
| Some a -> base_attrs @ a
| None -> base_attrs
in
El.li ?at:(if all_attrs = [] then None else Some all_attrs) children
let header ?classes ?attrs children =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let all_attrs = match attrs with
| Some a -> base_attrs @ a
| None -> base_attrs
in
El.header ?at:(if all_attrs = [] then None else Some all_attrs) children
let footer ?classes ?attrs children =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let all_attrs = match attrs with
| Some a -> base_attrs @ a
| None -> base_attrs
in
El.footer ?at:(if all_attrs = [] then None else Some all_attrs) children
let nav ?classes ?attrs children =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let all_attrs = match attrs with
| Some a -> base_attrs @ a
| None -> base_attrs
in
El.nav ?at:(if all_attrs = [] then None else Some all_attrs) children
let main ?classes ?attrs children =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let all_attrs = match attrs with
| Some a -> base_attrs @ a
| None -> base_attrs
in
El.main ?at:(if all_attrs = [] then None else Some all_attrs) children
(* Simplified div function that matches existing usage *)
let div_simple ?classes ?attrs children =
let base_attrs = match classes with
| Some c -> [classes_attr c]
| None -> []
in
let all_attrs = match attrs with
| Some a -> base_attrs @ a
| None -> base_attrs
in
El.div ?at:(if all_attrs = [] then None else Some all_attrs) children