+275
README.md
···+- **`tailwind-html`**: HTML component library built on top of [Htmlit](https://github.com/dbuenzli/htmlit)
+5
dune-project
···
+8
-10
examples/advanced_features.ml
············
+10
-10
examples/basic_usage.ml
···
+287
examples/complete_demo.ml
···+])] [El.txt "Build beautiful, responsive web interfaces with the power of OCaml's type system and Tailwind's utility classes."];+Tailwind.Responsive.(to_class (at_breakpoint `Md (Tailwind.Grid.(to_class (template_cols (`Cols 2))))));+Tailwind.Responsive.(to_class (at_breakpoint `Lg (Tailwind.Grid.(to_class (template_cols (`Cols 3))))));+Tailwind.Responsive.(to_class (at_breakpoint `Md (Tailwind.Spacing.(to_class (p (Tailwind.Size.rem 1.5))))));+Tailwind.Responsive.(to_class (at_breakpoint `Lg (Tailwind.Spacing.(to_class (p (Tailwind.Size.rem 2.0))))));+Tailwind.Responsive.(to_class (media `Dark (Tailwind.Color.bg (Tailwind.Color.make `Gray ~variant:`V800 ()))));
+252
examples/comprehensive_showcase_07.ml
···+])] [El.txt "Build beautiful, responsive web interfaces with OCaml's type system and Tailwind's utility classes."];+El.button ~at:[At.class' "btn-ghost text-white hover:bg-white hover:text-gray-900"] [El.txt "📖 View Docs"];+El.div ~at:[At.class' "w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center mb-4"] [+El.div ~at:[At.class' "w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center mb-4"] [+El.div ~at:[At.class' "w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center mb-4"] [+El.div ~at:[At.class' "w-12 h-12 bg-red-100 rounded-lg flex items-center justify-center mb-4"] [+El.div ~at:[At.class' "w-12 h-12 bg-yellow-100 rounded-lg flex items-center justify-center mb-4"] [+El.div ~at:[At.class' "w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-4"] [
+77
examples/improved_api_demo.ml
···
+80
examples/index_00.ml
···
+260
examples/layout_and_spacing_03.ml
···
+8
-8
examples/module_usage.ml
············
+188
examples/responsive_design_04.ml
···+El.txt "Resize your browser window to see responsive changes. The indicator in the top-right shows the current breakpoint."+El.txt "This text scales: small on mobile, base on tablet, and larger on desktop. The heading above also scales responsively."+Printf.printf "\n✅ Generated: 04_responsive_design.html (%d bytes)\n" (String.length html_string);
+95
examples/simple_html_example.ml
···+Printf.printf "HTML preview:\n%s\n" (String.sub html_string 0 (min 500 (String.length html_string)));+Tailwind.Responsive.(to_class (at_breakpoint `Md (Tailwind.Grid.(to_class (template_cols (`Cols 2))))));+Tailwind.Responsive.(to_class (at_breakpoint `Lg (Tailwind.Grid.(to_class (template_cols (`Cols 3))))));
+18
examples/tailwind_html_example.ml
···
+190
lib/tailwind-html/card.ml
···+let make ?variant ?header ?footer ?image ?(padding=true) ?(hoverable=false) ?(clickable=false) ?classes ?attributes ~children () = {+(if card.padding then Tailwind.Spacing.(to_class (p (Tailwind.Size.rem 1.5))) else Tailwind.Css.empty);+(if card.hoverable then Tailwind.Variants.hover (Tailwind.Effects.shadow_md) else Tailwind.Css.empty);+| `Sm n -> acc @ [Tailwind.Responsive.(to_class (at_breakpoint `Sm (Tailwind.Grid.(to_class (template_cols (`Cols n))))))]+| `Md n -> acc @ [Tailwind.Responsive.(to_class (at_breakpoint `Md (Tailwind.Grid.(to_class (template_cols (`Cols n))))))]+| `Lg n -> acc @ [Tailwind.Responsive.(to_class (at_breakpoint `Lg (Tailwind.Grid.(to_class (template_cols (`Cols n))))))]+| `Xl n -> acc @ [Tailwind.Responsive.(to_class (at_breakpoint `Xl (Tailwind.Grid.(to_class (template_cols (`Cols n))))))]
+227
lib/tailwind-html/component.ml
···
+17
-1
lib/tailwind-html/component.mli
···+val div_simple : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> Htmlit.El.html list -> Htmlit.El.html+val p : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> Htmlit.El.html list -> Htmlit.El.html+val h1 : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> Htmlit.El.html list -> Htmlit.El.html+val h2 : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> Htmlit.El.html list -> Htmlit.El.html+val h3 : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> Htmlit.El.html list -> Htmlit.El.html+val img : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> src:string -> alt:string -> unit -> Htmlit.El.html+val a : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> href:string -> Htmlit.El.html list -> Htmlit.El.html+val ul : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> Htmlit.El.html list -> Htmlit.El.html+val ol : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> Htmlit.El.html list -> Htmlit.El.html+val li : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> Htmlit.El.html list -> Htmlit.El.html+val header : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> Htmlit.El.html list -> Htmlit.El.html+val footer : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> Htmlit.El.html list -> Htmlit.El.html+val nav : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> Htmlit.El.html list -> Htmlit.El.html+val main : ?classes:Tailwind.t -> ?attrs:Htmlit.At.t list -> Htmlit.El.html list -> Htmlit.El.html
+2
-3
lib/tailwind-html/dune
···
+296
lib/tailwind-html/form.ml
···+Tailwind.Variants.focus (Tailwind.Color.border (Tailwind.Color.make `Green ~variant:`V600 ()));+Tailwind.Variants.focus (Tailwind.Color.border (Tailwind.Color.make `Yellow ~variant:`V600 ()));+let input ?input_type ?label ?placeholder ?value ?name ?id ?required ?disabled ?readonly ?validation ?helper_text ?error_text ?classes ?attributes () = {+let textarea ?label ?placeholder ?value ?name ?id ?rows ?required ?disabled ?readonly ?validation ?helper_text ?error_text ?classes ?attributes () = {+let select ?label ?name ?id ?required ?disabled ?validation ?helper_text ?error_text ?classes ?attributes ~options () = {
+197
lib/tailwind-html/layout.ml
···+| Flex of Tailwind.Flexbox.direction option * Tailwind.Flexbox.justify option * Tailwind.Flexbox.align_items option * Tailwind.Flexbox.wrap option * Tailwind.Size.t option+| Grid of Tailwind.Grid.cols option * Tailwind.Grid.rows option * Tailwind.Size.t option * Tailwind.Size.t option * Tailwind.Size.t option * Tailwind.Grid.flow option+| Row of Tailwind.Size.t option * Tailwind.Flexbox.justify option * Tailwind.Flexbox.align_items option * bool option+| Sidebar of [`Left | `Right] option * Tailwind.Size.t option * bool option * El.html * El.html+let padding_class = if padding then Tailwind.Spacing.(to_class (px (Tailwind.Size.rem 1.0))) else Tailwind.Css.empty in+let dir_classes = match direction with Some d -> [Tailwind.Flexbox.(to_class (direction d))] | None -> [] in+let justify_classes = match justify with Some j -> [Tailwind.Flexbox.(to_class (justify j))] | None -> [] in+let align_classes = match align with Some a -> [Tailwind.Flexbox.(to_class (align_items a))] | None -> [] in+let wrap_classes = match wrap with Some w -> [Tailwind.Flexbox.(to_class (wrap w))] | None -> [] in+let gap_classes = match gap with Some g -> [Tailwind.Spacing.(to_class (gap `All g))] | None -> [] in+Tailwind.tw ([Tailwind.Display.flex] @ dir_classes @ justify_classes @ align_classes @ wrap_classes @ gap_classes)+let col_classes = match cols with Some c -> [Tailwind.Grid.(to_class (template_cols c))] | None -> [] in+let row_classes = match rows with Some r -> [Tailwind.Grid.(to_class (template_rows r))] | None -> [] in+let gap_classes = match gap with Some g -> [Tailwind.Spacing.(to_class (gap `All g))] | None -> [] in+let gap_x_classes = match gap_x with Some g -> [Tailwind.Spacing.(to_class (gap `X g))] | None -> [] in+let gap_y_classes = match gap_y with Some g -> [Tailwind.Spacing.(to_class (gap `Y g))] | None -> [] in+Tailwind.tw ([Tailwind.Display.grid] @ col_classes @ row_classes @ gap_classes @ gap_x_classes @ gap_y_classes @ flow_classes)+let gap_classes = match gap with Some g -> [Tailwind.Spacing.(to_class (gap `All g))] | None -> [] in+let align_classes = match align with Some a -> [Tailwind.Flexbox.(to_class (align_items a))] | None -> [] in+Tailwind.tw ([Tailwind.Display.flex; Tailwind.Flexbox.(to_class (direction `Col))] @ gap_classes @ align_classes)+let gap_classes = match gap with Some g -> [Tailwind.Spacing.(to_class (gap `All g))] | None -> [] in+let justify_classes = match justify with Some j -> [Tailwind.Flexbox.(to_class (justify j))] | None -> [] in+let align_classes = match align with Some a -> [Tailwind.Flexbox.(to_class (align_items a))] | None -> [] in+let wrap_classes = match wrap with Some true -> [Tailwind.Flexbox.(to_class (wrap `Wrap))] | Some false -> [Tailwind.Flexbox.(to_class (wrap `Nowrap))] | None -> [] in+Tailwind.tw ([Tailwind.Display.flex; Tailwind.Flexbox.(to_class (direction `Row))] @ gap_classes @ justify_classes @ align_classes @ wrap_classes)+Tailwind.tw [Tailwind.Display.flex; Tailwind.Flexbox.(to_class (direction `Col)); Tailwind.Layout.h_screen]
+70
lib/tailwind-html/tailwind_html.ml
···+let size_styles = match size with Some s -> [Tailwind.Typography.(to_class (font_size s))] | None -> [] in+let weight_styles = match weight with Some w -> [Tailwind.Typography.(to_class (font_weight w))] | None -> [] in+let align_styles = match align with Some a -> [Tailwind.Typography.(to_class (text_align a))] | None -> [] in+let text_classes = Tailwind.tw (base_styles @ size_styles @ weight_styles @ color_styles @ align_styles) in
+11
lib/tailwind-html/tailwind_html.mli
···
+52
-56
lib/tailwind/color.ml
·········
+9
-12
lib/tailwind/color.mli
···
+39
-40
lib/tailwind/display.ml
···
+15
-16
lib/tailwind/display.mli
···
+1
-1
lib/tailwind/dune
···-(modules css color spacing size layout display flexbox grid position typography effects responsive variants tailwind))+(modules css color spacing size layout display flexbox grid position typography effects responsive variants reset patterns tailwind))
+112
-85
lib/tailwind/effects.ml
···-type transform_origin = Center | Top | Top_right | Right | Bottom_right | Bottom | Bottom_left | Left | Top_left+type transform_origin = [ `Center | `Top | `Top_right | `Right | `Bottom_right | `Bottom | `Bottom_left | `Left | `Top_left ]-| Rounded (_, _) -> Css.empty (* This should be handled by the specific rounded patterns above *)-| Border_width (_, _) -> Css.empty (* This should be handled by the specific border patterns above *)+| `Rounded (_, _) -> Css.empty (* This should be handled by the specific rounded patterns above *)+| `Border_width (_, _) -> Css.empty (* This should be handled by the specific border patterns above *)···
+38
-12
lib/tailwind/effects.mli
······
+115
-108
lib/tailwind/flexbox.ml
···
+47
-41
lib/tailwind/flexbox.mli
···
+69
-64
lib/tailwind/grid.ml
···
+24
-20
lib/tailwind/grid.mli
···
+87
-82
lib/tailwind/layout.ml
···
+22
-18
lib/tailwind/layout.mli
···
+63
lib/tailwind/patterns.ml
···
+25
lib/tailwind/patterns.mli
···
+48
-45
lib/tailwind/position.ml
······
+18
-16
lib/tailwind/position.mli
···
+37
lib/tailwind/reset.ml
···
+16
lib/tailwind/reset.mli
···
+51
-50
lib/tailwind/responsive.ml
···-type media_feature = Dark | Light | Motion_safe | Motion_reduce | Contrast_more | Contrast_less | Portrait | Landscape | Print | Screen+type media_feature = [ `Dark | `Light | `Motion_safe | `Motion_reduce | `Contrast_more | `Contrast_less | `Portrait | `Landscape | `Print | `Screen ]
+32
-29
lib/tailwind/responsive.mli
···
+29
-30
lib/tailwind/size.ml
···
+11
-12
lib/tailwind/size.mli
···
+34
-33
lib/tailwind/spacing.ml
·········
+11
-10
lib/tailwind/spacing.mli
···
+24
-72
lib/tailwind/tailwind.ml
·········
+13
-25
lib/tailwind/tailwind.mli
······
+86
-85
lib/tailwind/typography.ml
···-type font_weight = Thin | Extralight | Light | Normal | Medium | Semibold | Bold | Extrabold | Black+type font_size = [ `Xs | `Sm | `Base | `Lg | `Xl | `Xl2 | `Xl3 | `Xl4 | `Xl5 | `Xl6 | `Xl7 | `Xl8 | `Xl9 ]+type font_weight = [ `Thin | `Extralight | `Light | `Normal | `Medium | `Semibold | `Bold | `Extrabold | `Black ]
+34
-25
lib/tailwind/typography.mli
···
+71
-70
lib/tailwind/variants.ml
···-type pseudo_element = Before | After | First_line | First_letter | Marker | Selection | File | Backdrop | Placeholder+type pseudo_element = [ `Before | `After | `First_line | `First_letter | `Marker | `Selection | `File | `Backdrop | `Placeholder ]-type structural = First | Last | Only | Odd | Even | First_of_type | Last_of_type | Only_of_type | Empty | Root | Nth of int | Nth_last of int+type structural = [ `First | `Last | `Only | `Odd | `Even | `First_of_type | `Last_of_type | `Only_of_type | `Empty | `Root | `Nth of int | `Nth_last of int ]-type special = Not of pseudo | Has of string | Where of string | Is of string | Starting_style | Inert | Open | In of string+type special = [ `Not of pseudo | `Has of string | `Where of string | `Is of string | `Starting_style | `Inert | `Open | `In of string ]-| Structural (Nth n, classes) -> Css.make (Printf.sprintf "nth-child(%d):" n ^ Css.to_string classes)-| Structural (Nth_last n, classes) -> Css.make (Printf.sprintf "nth-last-child(%d):" n ^ Css.to_string classes)+| `Pseudo_element (`First_letter, classes) -> Css.make ("first-letter:" ^ Css.to_string classes)+| `Structural (`Nth n, classes) -> Css.make (Printf.sprintf "nth-child(%d):" n ^ Css.to_string classes)+| `Structural (`Nth_last n, classes) -> Css.make (Printf.sprintf "nth-last-child(%d):" n ^ Css.to_string classes)-| Special (Has selector, classes) -> Css.make ("has-[" ^ selector ^ "]:" ^ Css.to_string classes)-| Special (Where selector, classes) -> Css.make ("where-[" ^ selector ^ "]:" ^ Css.to_string classes)-| Special (Is selector, classes) -> Css.make ("is-[" ^ selector ^ "]:" ^ Css.to_string classes)+| `Special (`Has selector, classes) -> Css.make ("has-[" ^ selector ^ "]:" ^ Css.to_string classes)+| `Special (`Where selector, classes) -> Css.make ("where-[" ^ selector ^ "]:" ^ Css.to_string classes)+| `Special (`Is selector, classes) -> Css.make ("is-[" ^ selector ^ "]:" ^ Css.to_string classes)
+61
-56
lib/tailwind/variants.mli
···
+2
tailwind-html.opam
+2
tailwind.opam
+10
test/dune
+50
test/test_color.ml
···+Alcotest.(check bool) "full opacity contains /100" (String.contains_s (Css.to_string bg2) "/100")
+43
test/test_css.ml
···
+50
test/test_effects.ml
···
+72
test/test_patterns.ml
···
+7
test/test_runner.ml
+25
test/test_simple.ml
···
+61
test/test_tailwind.ml
···