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