Tailwind classes in OCaml
1type t = Css.t 2 3(* Module aliases *) 4module Css = Css 5module Color = Color 6module Size = Size 7module Spacing = Spacing 8module Display = Display 9module Flexbox = Flexbox 10module Grid = Grid 11module Position = Position 12module Layout = Layout 13module Typography = Typography 14module Effects = Effects 15module Responsive = Responsive 16module Variants = Variants 17 18let tw classes = Css.concat classes 19 20let class_list pairs = 21 List.fold_left (fun acc (classes, condition) -> 22 if condition then Css.combine acc classes else acc 23 ) Css.empty pairs 24 25let to_string = Css.to_string 26 27(* Common utility patterns *) 28let flex_center = 29 tw [ 30 Display.to_class Flex; 31 Flexbox.(to_class (justify Center)); 32 Flexbox.(to_class (align_items Center)); 33 ] 34 35let absolute_center = 36 tw [ 37 Css.make "absolute"; 38 Css.make "top-1/2"; 39 Css.make "left-1/2"; 40 Css.make "-translate-x-1/2"; 41 Css.make "-translate-y-1/2"; 42 ] 43 44let sr_only = 45 tw [ 46 Css.make "sr-only"; 47 ] 48 49let focus_ring ?color ?width () = 50 let base_classes = [ 51 Css.make "focus:outline-none"; 52 Css.make "focus:ring-2"; 53 Css.make "focus:ring-offset-2"; 54 ] in 55 let color_class = match color with 56 | Some c -> [Color.ring c] 57 | None -> [Css.make "focus:ring-blue-500"] 58 in 59 let width_class = match width with 60 | Some _ -> [] (* Could implement width variations *) 61 | None -> [] 62 in 63 tw (base_classes @ color_class @ width_class) 64 65let container ?center () = 66 let base = Css.make "container" in 67 let center_class = match center with 68 | Some true -> Css.make "mx-auto" 69 | _ -> Css.empty 70 in 71 Css.combine base center_class 72 73let button_reset = 74 tw [ 75 Css.make "border-0"; 76 Css.make "bg-transparent"; 77 Css.make "p-0"; 78 Css.make "cursor-pointer"; 79 ] 80 81let input_reset = 82 tw [ 83 Css.make "border-0"; 84 Css.make "outline-none"; 85 Css.make "bg-transparent"; 86 Css.make "appearance-none"; 87 ] 88 89let transition transition_type = 90 let class_name = match transition_type with 91 | `None -> "transition-none" 92 | `All -> "transition-all" 93 | `Colors -> "transition-colors" 94 | `Opacity -> "transition-opacity" 95 | `Shadow -> "transition-shadow" 96 | `Transform -> "transition-transform" 97 in 98 Css.make class_name 99 100let duration ms = Css.make (Printf.sprintf "duration-%d" ms) 101 102let ease timing = 103 let class_name = match timing with 104 | `Linear -> "ease-linear" 105 | `In -> "ease-in" 106 | `Out -> "ease-out" 107 | `In_out -> "ease-in-out" 108 in 109 Css.make class_name 110 111module V4 = struct 112 let container_query size classes = 113 let container_class = match size with 114 | Responsive.Xs -> "@xs:" 115 | Responsive.Sm -> "@sm:" 116 | Responsive.Md -> "@md:" 117 | Responsive.Lg -> "@lg:" 118 | Responsive.Xl -> "@xl:" 119 | Responsive.Xl2 -> "@2xl:" 120 | Responsive.Xl3 -> "@3xl:" 121 | Responsive.Xl4 -> "@4xl:" 122 | Responsive.Xl5 -> "@5xl:" 123 | Responsive.Xl6 -> "@6xl:" 124 | Responsive.Xl7 -> "@7xl:" 125 in 126 Css.make (container_class ^ Css.to_string classes) 127 128 let starting_style classes = 129 Css.make ("@starting-style " ^ Css.to_string classes) 130 131 let text_shadow shadow_size = 132 let class_name = match shadow_size with 133 | `None -> "text-shadow-none" 134 | `Sm -> "text-shadow-sm" 135 | `Base -> "text-shadow" 136 | `Lg -> "text-shadow-lg" 137 | `Xl -> "text-shadow-xl" 138 in 139 Css.make class_name 140 141 let mask mask_type = 142 let class_name = match mask_type with 143 | `Auto -> "mask-auto" 144 | `Cover -> "mask-cover" 145 | `Contain -> "mask-contain" 146 in 147 Css.make class_name 148 149 let perspective perspective_type = 150 let class_name = match perspective_type with 151 | `None -> "perspective-none" 152 | `Distant -> "perspective-distant" 153 | `Normal -> "perspective-normal" 154 | `Near -> "perspective-near" 155 in 156 Css.make class_name 157end