···
(* Main module for Tailwind HTML library *)
(* Common utility for converting Tailwind classes to HTML class attribute *)
let classes_attr tailwind_classes =
Htmlit.At.class' (Tailwind.to_string tailwind_classes)
···
let img ?classes ?attributes ~src ~alt () =
let attrs = match attributes with Some a -> a | None -> [] in
el "img" ?classes ~attributes:(("src", src) :: ("alt", alt) :: attrs) []
let ul ?classes ?attributes children = el "ul" ?classes ?attributes children
let ol ?classes ?attributes children = el "ol" ?classes ?attributes children
let li ?classes ?attributes children = el "li" ?classes ?attributes children
+
(* Utility functions for colors and sizes *)
+
let blue variant = Tailwind.Color.make `Blue ~variant:(match variant with
+
| 50 -> `V50 | 100 -> `V100 | 200 -> `V200 | 300 -> `V300 | 400 -> `V400
+
| 500 -> `V500 | 600 -> `V600 | 700 -> `V700 | 800 -> `V800 | 900 -> `V900
+
let gray variant = Tailwind.Color.make `Gray ~variant:(match variant with
+
| 50 -> `V50 | 100 -> `V100 | 200 -> `V200 | 300 -> `V300 | 400 -> `V400
+
| 500 -> `V500 | 600 -> `V600 | 700 -> `V700 | 800 -> `V800 | 900 -> `V900
+
let red variant = Tailwind.Color.make `Red ~variant:(match variant with
+
| 50 -> `V50 | 100 -> `V100 | 200 -> `V200 | 300 -> `V300 | 400 -> `V400
+
| 500 -> `V500 | 600 -> `V600 | 700 -> `V700 | 800 -> `V800 | 900 -> `V900
+
let green variant = Tailwind.Color.make `Green ~variant:(match variant with
+
| 50 -> `V50 | 100 -> `V100 | 200 -> `V200 | 300 -> `V300 | 400 -> `V400
+
| 500 -> `V500 | 600 -> `V600 | 700 -> `V700 | 800 -> `V800 | 900 -> `V900
+
let rem f = Tailwind.Size.rem f
+
let px = Tailwind.Size.px
+
let zero = Tailwind.Size.zero
+
let auto = Tailwind.Size.auto
+
let full = Tailwind.Size.full
+
let screen = Tailwind.Size.screen
+
let txt s = Htmlit.El.txt s
+
(* Common utility classes *)
+
let flex = Tailwind.Display.flex
+
let flex_col = Tailwind.Flexbox.(to_class (direction `Col))
+
let items_center = Tailwind.Flexbox.(to_class (align_items `Center))
+
let justify_center = Tailwind.Flexbox.(to_class (justify `Center))
+
let justify_between = Tailwind.Flexbox.(to_class (justify `Between))
+
let font_bold = Tailwind.Typography.(to_class (font_weight `Bold))
+
let font_semibold = Tailwind.Typography.(to_class (font_weight `Semibold))
+
let text_center = Tailwind.Typography.(to_class (text_align `Center))
+
let w_full = Tailwind.Layout.w_full
+
let h_full = Tailwind.Layout.h_full
+
let rounded_lg = Tailwind.Effects.rounded_lg
+
let rounded_md = Tailwind.Effects.rounded_md
+
let shadow_md = Tailwind.Effects.shadow_md
+
let shadow_lg = Tailwind.Effects.shadow_lg
+
(* Enhanced element functions with styling parameters *)
+
let h1 ?size ?weight ?color ?align ?mb ?classes children =
+
let base_styles = [Tailwind.Typography.(to_class (font_size `Xl2)); font_bold] in
+
let size_styles = match size with
+
| Some `Xl -> [Tailwind.Typography.(to_class (font_size `Xl))]
+
| Some `Xl2 -> [Tailwind.Typography.(to_class (font_size `Xl2))]
+
| Some `Xl3 -> [Tailwind.Typography.(to_class (font_size `Xl3))]
+
| Some `Xl4 -> [Tailwind.Typography.(to_class (font_size `Xl4))]
+
let weight_styles = match weight with
+
| Some `Bold -> [font_bold]
+
| Some `Semibold -> [font_semibold]
+
| Some `Medium -> [Tailwind.Typography.(to_class (font_weight `Medium))]
+
let color_styles = match color with Some c -> [Tailwind.Color.text c] | None -> [] in
+
let align_styles = match align with
+
| Some `Center -> [text_center]
+
| Some `Left -> [Tailwind.Typography.(to_class (text_align `Left))]
+
| Some `Right -> [Tailwind.Typography.(to_class (text_align `Right))]
+
let spacing_styles = match mb with Some s -> [Tailwind.Spacing.(to_class (mb s))] | None -> [] in
+
let final_classes = Tailwind.Css.tw (base_styles @ size_styles @ weight_styles @ color_styles @ align_styles @ spacing_styles @
+
(match classes with Some c -> [c] | None -> [])) in
+
Htmlit.El.h1 ~at:[classes_attr final_classes] children
+
let h2 ?size ?weight ?color ?align ?mb ?classes children =
+
let base_styles = [Tailwind.Typography.(to_class (font_size `Xl)); font_semibold] in
+
let size_styles = match size with
+
| Some `Lg -> [Tailwind.Typography.(to_class (font_size `Lg))]
+
| Some `Xl -> [Tailwind.Typography.(to_class (font_size `Xl))]
+
| Some `Xl2 -> [Tailwind.Typography.(to_class (font_size `Xl2))]
+
let weight_styles = match weight with
+
| Some `Bold -> [font_bold]
+
| Some `Semibold -> [font_semibold]
+
| Some `Medium -> [Tailwind.Typography.(to_class (font_weight `Medium))]
+
let color_styles = match color with Some c -> [Tailwind.Color.text c] | None -> [] in
+
let align_styles = match align with
+
| Some `Center -> [text_center]
+
| Some `Left -> [Tailwind.Typography.(to_class (text_align `Left))]
+
| Some `Right -> [Tailwind.Typography.(to_class (text_align `Right))]
+
let spacing_styles = match mb with Some s -> [Tailwind.Spacing.(to_class (mb s))] | None -> [] in
+
let final_classes = Tailwind.Css.tw (base_styles @ size_styles @ weight_styles @ color_styles @ align_styles @ spacing_styles @
+
(match classes with Some c -> [c] | None -> [])) in
+
Htmlit.El.h2 ~at:[classes_attr final_classes] children
+
let p_styled ?size ?color ?align ?mb ?classes children =
+
let base_styles = [Tailwind.Typography.(to_class (font_size `Base))] in
+
let size_styles = match size with
+
| Some `Sm -> [Tailwind.Typography.(to_class (font_size `Sm))]
+
| Some `Base -> [Tailwind.Typography.(to_class (font_size `Base))]
+
| Some `Lg -> [Tailwind.Typography.(to_class (font_size `Lg))]
+
let color_styles = match color with Some c -> [Tailwind.Color.text c] | None -> [] in
+
let align_styles = match align with
+
| Some `Center -> [text_center]
+
| Some `Left -> [Tailwind.Typography.(to_class (text_align `Left))]
+
| Some `Right -> [Tailwind.Typography.(to_class (text_align `Right))]
+
let spacing_styles = match mb with Some s -> [Tailwind.Spacing.(to_class (mb s))] | None -> [] in
+
let final_classes = Tailwind.Css.tw (base_styles @ size_styles @ color_styles @ align_styles @ spacing_styles @
+
(match classes with Some c -> [c] | None -> [])) in
+
Htmlit.El.p ~at:[classes_attr final_classes] children
+
(* Simple component functions *)
+
let container children =
+
let container_classes = Tailwind.Css.tw [Tailwind.Patterns.container ()] in
+
div ~classes:container_classes children
+
let flex_center children =
+
let flex_classes = Tailwind.Css.tw [flex; items_center; justify_center] in
+
div ~classes:flex_classes children
+
let card ?elevated ?padding children =
+
let base_classes = [Tailwind.Color.bg Tailwind.Color.white; rounded_lg] in
+
let shadow_classes = if elevated = Some true then [shadow_lg] else [Tailwind.Effects.shadow_sm] in
+
let padding_classes = if padding <> Some false then [Tailwind.Spacing.(to_class (p (rem 1.5)))] else [] in
+
let card_classes = Tailwind.Css.tw (base_classes @ shadow_classes @ padding_classes) in
+
div ~classes:card_classes children
+
let btn_primary ?size ?disabled children =
+
flex; items_center; justify_center; rounded_md;
+
Tailwind.Typography.(to_class (font_size `Sm));
+
Tailwind.Typography.(to_class (font_weight `Medium));
+
Tailwind.Color.bg (blue 600);
+
Tailwind.Color.text Tailwind.Color.white;
+
Tailwind.Variants.hover (Tailwind.Color.bg (blue 700));
+
Tailwind.Effects.transition `Colors;
+
let size_classes = match size with
+
| Some `Sm -> [Tailwind.Spacing.(to_class (px (rem 0.75))); Tailwind.Spacing.(to_class (py (rem 0.375)))]
+
| Some `Lg -> [Tailwind.Spacing.(to_class (px (rem 2.0))); Tailwind.Spacing.(to_class (py (rem 0.75)))]
+
| _ -> [Tailwind.Spacing.(to_class (px (rem 1.0))); Tailwind.Spacing.(to_class (py (rem 0.5)))]
+
let disabled_classes = if disabled = Some true then [
+
Tailwind.Css.make "disabled:opacity-50";
+
Tailwind.Css.make "disabled:cursor-not-allowed"
+
let btn_classes = Tailwind.Css.tw (base_classes @ size_classes @ disabled_classes) in
+
let attrs = [classes_attr btn_classes] @ (if disabled = Some true then [Htmlit.At.disabled] else []) in
+
Htmlit.El.button ~at:attrs children
+
let btn_secondary ?size ?disabled children =
+
flex; items_center; justify_center; rounded_md;
+
Tailwind.Typography.(to_class (font_size `Sm));
+
Tailwind.Typography.(to_class (font_weight `Medium));
+
Tailwind.Color.bg (gray 200);
+
Tailwind.Color.text (gray 900);
+
Tailwind.Variants.hover (Tailwind.Color.bg (gray 300));
+
Tailwind.Effects.transition `Colors;
+
let size_classes = match size with
+
| Some `Sm -> [Tailwind.Spacing.(to_class (px (rem 0.75))); Tailwind.Spacing.(to_class (py (rem 0.375)))]
+
| Some `Lg -> [Tailwind.Spacing.(to_class (px (rem 2.0))); Tailwind.Spacing.(to_class (py (rem 0.75)))]
+
| _ -> [Tailwind.Spacing.(to_class (px (rem 1.0))); Tailwind.Spacing.(to_class (py (rem 0.5)))]
+
let disabled_classes = if disabled = Some true then [
+
Tailwind.Css.make "disabled:opacity-50";
+
Tailwind.Css.make "disabled:cursor-not-allowed"
+
let btn_classes = Tailwind.Css.tw (base_classes @ size_classes @ disabled_classes) in
+
let attrs = [classes_attr btn_classes] @ (if disabled = Some true then [Htmlit.At.disabled] else []) in
+
Htmlit.El.button ~at:attrs children
(* Text element with built-in typography utilities *)
let text ?size ?weight ?color ?align ?classes text_content =