Tailwind classes in OCaml
1(* Example 04: Responsive Design - Building Adaptive Layouts *) 2 3open Htmlit 4open Tailwind 5 6let classes_attr tailwind_classes = 7 At.class' (Tailwind.to_string tailwind_classes) 8 9let create_responsive_demo () = 10 (* Create comprehensive responsive demonstration *) 11 let html_doc = El.html [ 12 El.head [ 13 El.meta ~at:[At.charset "utf-8"] (); 14 El.meta ~at:[At.name "viewport"; At.content "width=device-width, initial-scale=1"] (); 15 El.title [El.txt "Responsive Design"]; 16 El.link ~at:[At.rel "stylesheet"; At.href "responsive_design_04.css"] (); 17 ]; 18 El.body ~at:[At.class' "min-h-screen bg-gray-50 p-8"] [ 19 El.div ~at:[At.class' "max-w-6xl mx-auto"] [ 20 El.h1 ~at:[classes_attr (tw [ 21 Typography.(to_class (font_size `Xl2)); 22 Responsive.(to_class (at_breakpoint `Md (Typography.(to_class (font_size `Xl3))))); 23 Typography.(to_class (font_weight `Bold)); 24 Color.text (Color.make `Gray ~variant:`V700 ()); 25 ]); At.class' "mb-8 text-center"] [El.txt "Responsive Design Demo"]; 26 27 El.p ~at:[classes_attr (tw [ 28 Typography.(to_class (font_size `Lg)); 29 Color.text (Color.make `Gray ~variant:`V600 ()); 30 ]); At.class' "text-center mb-8"] [ 31 El.txt "Resize your browser window to see responsive changes. The indicator in the top-right shows the current breakpoint." 32 ]; 33 34 (* Responsive Grid *) 35 El.section ~at:[At.class' "mb-8"] [ 36 El.h2 ~at:[classes_attr (tw [ 37 Typography.(to_class (font_size `Xl)); 38 Typography.(to_class (font_weight `Semibold)); 39 Color.text (Color.make `Gray ~variant:`V700 ()); 40 ]); At.class' "mb-6"] [El.txt "Responsive Grid"]; 41 42 El.p ~at:[classes_attr (tw [ 43 Color.text (Color.make `Gray ~variant:`V600 ()); 44 ]); At.class' "mb-4"] [ 45 El.txt "1 column → 2 columns (md) → 3 columns (lg) → 4 columns (xl)" 46 ]; 47 48 El.div ~at:[classes_attr (tw [ 49 Display.grid; 50 Grid.(to_class (template_cols (`Cols 1))); 51 Responsive.(to_class (at_breakpoint `Md (Grid.(to_class (template_cols (`Cols 2)))))); 52 Responsive.(to_class (at_breakpoint `Lg (Grid.(to_class (template_cols (`Cols 3)))))); 53 Responsive.(to_class (at_breakpoint `Xl (Grid.(to_class (template_cols (`Cols 4)))))); 54 Spacing.(to_class (gap `All (Size.rem 1.0))); 55 ])] (List.init 8 (fun i -> 56 let colors = [| 57 Color.make `Blue ~variant:`V100 (); 58 Color.make `Green ~variant:`V100 (); 59 Color.make `Purple ~variant:`V100 (); 60 Color.make `Red ~variant:`V100 (); 61 Color.make `Yellow ~variant:`V100 (); 62 |] in 63 El.div ~at:[classes_attr (tw [ 64 Color.bg colors.(i mod (Array.length colors)); 65 Spacing.(to_class (p (Size.rem 1.5))); 66 ]); At.class' "rounded-lg text-center"] [ 67 El.txt (Printf.sprintf "Item %d" (i + 1)) 68 ] 69 )); 70 ]; 71 72 (* Responsive Typography *) 73 El.section ~at:[At.class' "mb-8"] [ 74 El.h2 ~at:[classes_attr (tw [ 75 Typography.(to_class (font_size `Xl)); 76 Typography.(to_class (font_weight `Semibold)); 77 Color.text (Color.make `Gray ~variant:`V700 ()); 78 ]); At.class' "mb-6"] [El.txt "Responsive Typography"]; 79 80 El.div ~at:[classes_attr (tw [ 81 Color.bg (Color.make `Gray ~variant:`V100 ()); 82 Spacing.(to_class (p (Size.rem 1.5))); 83 ]); At.class' "rounded-lg text-center"] [ 84 El.h3 ~at:[classes_attr (tw [ 85 Typography.(to_class (font_size `Base)); 86 Responsive.(to_class (at_breakpoint `Md (Typography.(to_class (font_size `Lg))))); 87 Responsive.(to_class (at_breakpoint `Lg (Typography.(to_class (font_size `Xl2))))); 88 Typography.(to_class (font_weight `Semibold)); 89 Color.text (Color.make `Blue ~variant:`V600 ()); 90 ]); At.class' "mb-4"] [El.txt "Responsive Heading"]; 91 92 El.p ~at:[classes_attr (tw [ 93 Typography.(to_class (font_size `Sm)); 94 Responsive.(to_class (at_breakpoint `Md (Typography.(to_class (font_size `Base))))); 95 Color.text (Color.make `Gray ~variant:`V600 ()); 96 ])] [ 97 El.txt "This text scales: small on mobile, base on tablet, and larger on desktop. The heading above also scales responsively." 98 ]; 99 ]; 100 ]; 101 102 (* Show/Hide Elements *) 103 El.section ~at:[At.class' "mb-8"] [ 104 El.h2 ~at:[classes_attr (tw [ 105 Typography.(to_class (font_size `Xl)); 106 Typography.(to_class (font_weight `Semibold)); 107 Color.text (Color.make `Gray ~variant:`V700 ()); 108 ]); At.class' "mb-6"] [El.txt "Responsive Visibility"]; 109 110 El.div ~at:[classes_attr (tw [ 111 Display.flex; 112 Flexbox.(to_class (direction `Col)); 113 Responsive.(to_class (at_breakpoint `Md (Flexbox.(to_class (direction `Row))))); 114 Spacing.(to_class (gap `All (Size.rem 1.0))); 115 ])] [ 116 El.div ~at:[classes_attr (tw [ 117 Color.bg (Color.make `Blue ~variant:`V100 ()); 118 Spacing.(to_class (p (Size.rem 1.5))); 119 ]); At.class' "rounded-lg text-center"] [ 120 El.txt "Always visible" 121 ]; 122 123 El.div ~at:[classes_attr (tw [ 124 Color.bg (Color.make `Green ~variant:`V100 ()); 125 Spacing.(to_class (p (Size.rem 1.5))); 126 Display.hidden; 127 Responsive.(to_class (at_breakpoint `Md Display.block)); 128 ]); At.class' "rounded-lg text-center"] [ 129 El.txt "Hidden on mobile, visible on md+" 130 ]; 131 132 El.div ~at:[classes_attr (tw [ 133 Color.bg (Color.make `Purple ~variant:`V100 ()); 134 Spacing.(to_class (p (Size.rem 1.5))); 135 Display.hidden; 136 Responsive.(to_class (at_breakpoint `Lg Display.block)); 137 ]); At.class' "rounded-lg text-center"] [ 138 El.txt "Only visible on lg+" 139 ]; 140 ]; 141 ]; 142 143 (* Responsive Spacing *) 144 El.section [ 145 El.h2 ~at:[classes_attr (tw [ 146 Typography.(to_class (font_size `Xl)); 147 Typography.(to_class (font_weight `Semibold)); 148 Color.text (Color.make `Gray ~variant:`V700 ()); 149 ]); At.class' "mb-6"] [El.txt "Responsive Spacing"]; 150 151 El.div ~at:[classes_attr (tw [ 152 Color.bg (Color.make `Gray ~variant:`V100 ()); 153 Spacing.(to_class (p (Size.rem 1.0))); 154 Responsive.(to_class (at_breakpoint `Md (Spacing.(to_class (p (Size.rem 1.5)))))); 155 Responsive.(to_class (at_breakpoint `Lg (Spacing.(to_class (p (Size.rem 2.0)))))); 156 ]); At.class' "rounded-lg"] [ 157 El.div ~at:[classes_attr (tw [ 158 Color.bg Color.white; 159 Spacing.(to_class (p (Size.rem 1.0))); 160 ]); At.class' "rounded"] [ 161 El.p [El.txt "This container has responsive padding:"]; 162 El.ul [ 163 El.li [El.txt "p-4 (1rem) on mobile"]; 164 El.li [El.txt "md:p-6 (1.5rem) on tablet"]; 165 El.li [El.txt "lg:p-8 (2rem) on desktop"]; 166 ]; 167 ]; 168 ]; 169 ]; 170 ]; 171 ]; 172 ] in 173 174 let html_string = El.to_string ~doctype:true html_doc in 175 let oc = open_out "04_responsive_design.html" in 176 output_string oc html_string; 177 close_out oc; 178 179 Printf.printf "\n✅ Generated: 04_responsive_design.html (%d bytes)\n" (String.length html_string); 180 Printf.printf "\n🎯 What you learned:\n"; 181 Printf.printf " • Mobile-first responsive design approach\n"; 182 Printf.printf " • Breakpoint system: sm, md, lg, xl\n"; 183 Printf.printf " • Responsive utilities with at_breakpoint function\n"; 184 Printf.printf " • Show/hide elements at different screen sizes\n"; 185 Printf.printf " • Responsive typography and spacing\n"; 186 Printf.printf " • Grid columns that adapt to screen size\n" 187 188let () = create_responsive_demo ()