···
1
+
(* Generate index.html page linking to all examples *)
6
+
let classes_attr tailwind_classes =
7
+
At.class' (Tailwind.to_string tailwind_classes)
10
+
("hello_tailwind_01.html", "01. Hello Tailwind",
11
+
"Your first Tailwind OCaml program. Learn the basics of creating and using type-safe Tailwind classes.",
12
+
["Basic concepts"; "Type safety"; "Class composition"]);
14
+
("colors_and_typography_02.html", "02. Colors and Typography",
15
+
"Explore the comprehensive color system and typography utilities with compile-time validation.",
16
+
["Color variants"; "Typography scale"; "Font weights"]);
18
+
("layout_and_spacing_03.html", "03. Layout and Spacing",
19
+
"Master the box model, flexbox layouts, and spacing utilities for building structured interfaces.",
20
+
["Box model"; "Flexbox"; "Spacing system"]);
22
+
("responsive_design_04.html", "04. Responsive Design",
23
+
"Learn responsive design patterns with breakpoints and mobile-first utilities.",
24
+
["Breakpoints"; "Mobile-first"; "Responsive utilities"]);
26
+
("effects_and_variants_05.html", "05. Effects and Variants",
27
+
"Add visual effects and interactive states with shadows, borders, and hover variants.",
28
+
["Visual effects"; "Interactive states"; "Hover variants"]);
30
+
("patterns_and_components_06.html", "06. Patterns and Components",
31
+
"Build reusable layout patterns and component compositions for consistent design.",
32
+
["Layout patterns"; "Component composition"; "Reusable utilities"]);
34
+
("comprehensive_showcase_07.html", "07. Comprehensive Showcase",
35
+
"Complete application demo showcasing all library features in a real-world context.",
36
+
["Complete application"; "All features"; "Best practices"]);
39
+
let create_index_page () =
40
+
let page_classes = tw [
41
+
Layout.(to_class (min_height Size.screen));
42
+
Color.bg (Color.make `Gray ~variant:`V50 ());
45
+
let container_classes = tw [
46
+
Layout.(to_class (max_width (Size.rem 72.0))); (* max-w-6xl *)
47
+
Spacing.(to_class (mx `Auto));
48
+
Spacing.(to_class (p (Size.rem 2.0)));
51
+
let header_classes = tw [
52
+
Typography.(to_class (font_size `Xl4));
53
+
Typography.(to_class (font_weight `Bold));
54
+
Color.text (Color.make `Gray ~variant:`V900 ());
55
+
Spacing.(to_class (mb (Size.rem 2.0)));
56
+
Typography.(to_class (text_align `Center));
59
+
let subtitle_classes = tw [
60
+
Typography.(to_class (font_size `Xl));
61
+
Color.text (Color.make `Gray ~variant:`V600 ());
62
+
Typography.(to_class (text_align `Center));
63
+
Spacing.(to_class (mb (Size.rem 3.0)));
66
+
let grid_classes = tw [
68
+
Grid.(to_class (template_cols (`Cols 1)));
69
+
Responsive.(to_class (at_breakpoint `Md (Grid.(to_class (template_cols (`Cols 2))))));
70
+
Spacing.(to_class (gap `All (Size.rem 1.5)));
71
+
Spacing.(to_class (mb (Size.rem 3.0)));
74
+
let card_classes = tw [
75
+
Color.bg Color.white;
78
+
Spacing.(to_class (p (Size.rem 1.5)));
80
+
Color.border (Color.make `Gray ~variant:`V200 ());
81
+
Effects.transition `All;
82
+
Variants.hover Effects.shadow_md;
83
+
Variants.hover (Color.border (Color.make `Blue ~variant:`V300 ()));
86
+
let card_title_classes = tw [
87
+
Typography.(to_class (font_size `Lg));
88
+
Typography.(to_class (font_weight `Semibold));
89
+
Color.text (Color.make `Gray ~variant:`V900 ());
90
+
Spacing.(to_class (mb (Size.rem 0.75)));
93
+
let card_description_classes = tw [
94
+
Color.text (Color.make `Gray ~variant:`V600 ());
95
+
Spacing.(to_class (mb (Size.rem 1.0)));
96
+
Typography.(to_class (line_height `Relaxed));
99
+
let features_classes = tw [
101
+
Flexbox.(to_class (wrap `Wrap));
102
+
Spacing.(to_class (gap `All (Size.rem 0.5)));
103
+
Spacing.(to_class (mb (Size.rem 1.0)));
106
+
let feature_tag_classes = tw [
107
+
Color.bg (Color.make `Blue ~variant:`V50 ());
108
+
Color.text (Color.make `Blue ~variant:`V700 ());
109
+
Typography.(to_class (font_size `Xs));
110
+
Spacing.(to_class (px (Size.rem 0.5)));
111
+
Spacing.(to_class (py (Size.rem 0.25)));
112
+
Effects.rounded_full;
115
+
let link_classes = tw [
116
+
Color.text (Color.make `Blue ~variant:`V600 ());
117
+
Typography.(to_class (font_weight `Medium));
118
+
Variants.hover (Color.text (Color.make `Blue ~variant:`V800 ()));
119
+
Effects.transition `Colors;
122
+
let footer_classes = tw [
123
+
Typography.(to_class (text_align `Center));
124
+
Spacing.(to_class (mt (Size.rem 3.0)));
125
+
Color.text (Color.make `Gray ~variant:`V500 ());
126
+
Typography.(to_class (font_size `Sm));
129
+
let html_doc = El.html [
131
+
El.meta ~at:[At.charset "utf-8"] ();
132
+
El.meta ~at:[At.name "viewport"; At.content "width=device-width, initial-scale=1"] ();
133
+
El.title [El.txt "Tailwind OCaml Examples"];
134
+
El.link ~at:[At.rel "stylesheet"; At.href "hello_tailwind_01.css"] (); (* Reuse CSS from first example *)
135
+
El.style [El.txt {|
136
+
body { font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; }
137
+
a { text-decoration: none; }
138
+
.example-card { display: block; }
141
+
El.body ~at:[classes_attr page_classes] [
142
+
El.div ~at:[classes_attr container_classes] [
143
+
El.h1 ~at:[classes_attr header_classes] [
144
+
El.txt "Tailwind OCaml Examples"
147
+
El.p ~at:[classes_attr subtitle_classes] [
148
+
El.txt "A progressive tutorial series demonstrating type-safe Tailwind CSS generation in OCaml"
151
+
El.div ~at:[classes_attr grid_classes] (
152
+
List.map (fun (href, title, description, features) ->
153
+
El.a ~at:[At.href href; At.class' "example-card"] [
154
+
El.div ~at:[classes_attr card_classes] [
155
+
El.h2 ~at:[classes_attr card_title_classes] [El.txt title];
156
+
El.p ~at:[classes_attr card_description_classes] [El.txt description];
157
+
El.div ~at:[classes_attr features_classes] (
158
+
List.map (fun feature ->
159
+
El.span ~at:[classes_attr feature_tag_classes] [El.txt feature]
162
+
El.div ~at:[classes_attr link_classes] [
163
+
El.txt "View Example →"
170
+
El.div ~at:[classes_attr footer_classes] [
172
+
El.txt "Built with ";
173
+
El.a ~at:[At.href "https://github.com/dbuenzli/htmlit"; classes_attr link_classes] [El.txt "Htmlit"];
174
+
El.txt " and type-safe Tailwind CSS generation"
183
+
(* Output HTML to stdout *)
184
+
let html_doc = create_index_page () in
185
+
let html_string = El.to_string ~doctype:true html_doc in
186
+
print_string html_string