Tailwind classes in OCaml
1(* Example 05: Effects and Variants - Interactive Elements and Visual Effects *)
2
3open Htmlit
4open Tailwind
5
6let classes_attr tailwind_classes =
7 At.class' (Tailwind.to_string tailwind_classes)
8
9let create_effects_demo () =
10
11 (* Create comprehensive effects demonstration *)
12 let html_doc = El.html [
13 El.head [
14 El.meta ~at:[At.charset "utf-8"] ();
15 El.meta ~at:[At.name "viewport"; At.content "width=device-width, initial-scale=1"] ();
16 El.title [El.txt "Effects and Variants"];
17 El.link ~at:[At.rel "stylesheet"; At.href "effects_and_variants_05.css"] ();
18 ];
19 El.body ~at:[At.class' "min-h-screen bg-gray-50 p-8"] [
20 El.div ~at:[At.class' "max-w-6xl mx-auto"] [
21 El.h1 ~at:[classes_attr (tw [
22 Typography.(to_class (font_size `Xl2));
23 Typography.(to_class (font_weight `Bold));
24 Color.text (Color.make `Gray ~variant:`V800 ());
25 ]); At.class' "mb-8 text-center"] [El.txt "Effects and Variants Demo"];
26
27 (* Shadow Effects *)
28 El.section ~at:[At.class' "mb-8"] [
29 El.h2 ~at:[classes_attr (tw [
30 Typography.(to_class (font_size `Xl));
31 Typography.(to_class (font_weight `Semibold));
32 Color.text (Color.make `Gray ~variant:`V700 ());
33 ]); At.class' "mb-6"] [El.txt "Shadow Effects"];
34
35 El.div ~at:[classes_attr (tw [
36 Display.grid;
37 Grid.(to_class (template_cols (`Cols 1)));
38 Responsive.(to_class (at_breakpoint `Md (Grid.(to_class (template_cols (`Cols 3))))));
39 Spacing.(to_class (gap `All (Size.rem 1.5)));
40 ])] [
41 El.div ~at:[classes_attr (tw [
42 Color.bg Color.white;
43 Spacing.(to_class (p (Size.rem 1.5)));
44 Effects.shadow_sm;
45 Effects.rounded_lg;
46 ]); At.class' "text-center"] [
47 El.h3 ~at:[classes_attr (tw [
48 Typography.(to_class (font_weight `Semibold));
49 Color.text (Color.make `Gray ~variant:`V700 ());
50 ]); At.class' "mb-2"] [El.txt "Small Shadow"];
51 El.p ~at:[classes_attr (tw [
52 Typography.(to_class (font_size `Sm));
53 Color.text (Color.make `Gray ~variant:`V600 ());
54 ])] [El.txt "shadow-sm"];
55 ];
56
57 El.div ~at:[classes_attr (tw [
58 Color.bg Color.white;
59 Spacing.(to_class (p (Size.rem 1.5)));
60 Effects.shadow_md;
61 Effects.rounded_lg;
62 ]); At.class' "text-center"] [
63 El.h3 ~at:[classes_attr (tw [
64 Typography.(to_class (font_weight `Semibold));
65 Color.text (Color.make `Gray ~variant:`V700 ());
66 ]); At.class' "mb-2"] [El.txt "Medium Shadow"];
67 El.p ~at:[classes_attr (tw [
68 Typography.(to_class (font_size `Sm));
69 Color.text (Color.make `Gray ~variant:`V600 ());
70 ])] [El.txt "shadow-md"];
71 ];
72
73 El.div ~at:[classes_attr (tw [
74 Color.bg Color.white;
75 Spacing.(to_class (p (Size.rem 1.5)));
76 Effects.shadow_lg;
77 Effects.rounded_lg;
78 ]); At.class' "text-center"] [
79 El.h3 ~at:[classes_attr (tw [
80 Typography.(to_class (font_weight `Semibold));
81 Color.text (Color.make `Gray ~variant:`V700 ());
82 ]); At.class' "mb-2"] [El.txt "Large Shadow"];
83 El.p ~at:[classes_attr (tw [
84 Typography.(to_class (font_size `Sm));
85 Color.text (Color.make `Gray ~variant:`V600 ());
86 ])] [El.txt "shadow-lg"];
87 ];
88 ];
89 ];
90
91 (* Rounded Corners *)
92 El.section ~at:[At.class' "mb-8"] [
93 El.h2 ~at:[classes_attr (tw [
94 Typography.(to_class (font_size `Xl));
95 Typography.(to_class (font_weight `Semibold));
96 Color.text (Color.make `Gray ~variant:`V700 ());
97 ]); At.class' "mb-6"] [El.txt "Border Radius"];
98
99 El.div ~at:[classes_attr (tw [
100 Display.flex;
101 Flexbox.(to_class (wrap `Wrap));
102 Spacing.(to_class (gap `All (Size.rem 1.0)));
103 Flexbox.(to_class (justify `Center));
104 ])] [
105 El.div ~at:[classes_attr (tw [
106 Color.bg (Color.make `Blue ~variant:`V100 ());
107 Spacing.(to_class (p (Size.rem 1.0)));
108 (* No rounded corners *)
109 ]); At.class' "text-center"] [El.txt "No Radius"];
110
111 El.div ~at:[classes_attr (tw [
112 Color.bg (Color.make `Green ~variant:`V100 ());
113 Spacing.(to_class (p (Size.rem 1.0)));
114 Effects.rounded_sm;
115 ]); At.class' "text-center"] [El.txt "Small"];
116
117 El.div ~at:[classes_attr (tw [
118 Color.bg (Color.make `Purple ~variant:`V100 ());
119 Spacing.(to_class (p (Size.rem 1.0)));
120 Effects.rounded_md;
121 ]); At.class' "text-center"] [El.txt "Medium"];
122
123 El.div ~at:[classes_attr (tw [
124 Color.bg (Color.make `Red ~variant:`V100 ());
125 Spacing.(to_class (p (Size.rem 1.0)));
126 Effects.rounded_lg;
127 ]); At.class' "text-center"] [El.txt "Large"];
128
129 El.div ~at:[classes_attr (tw [
130 Color.bg (Color.make `Yellow ~variant:`V100 ());
131 Spacing.(to_class (p (Size.rem 1.0)));
132 Effects.rounded_full;
133 ]); At.class' "text-center"] [El.txt "Full"];
134 ];
135 ];
136
137 (* Interactive Buttons *)
138 El.section ~at:[At.class' "mb-8"] [
139 El.h2 ~at:[classes_attr (tw [
140 Typography.(to_class (font_size `Xl));
141 Typography.(to_class (font_weight `Semibold));
142 Color.text (Color.make `Gray ~variant:`V700 ());
143 ]); At.class' "mb-6"] [El.txt "Interactive Buttons"];
144
145 El.div ~at:[classes_attr (tw [
146 Display.flex;
147 Flexbox.(to_class (wrap `Wrap));
148 Spacing.(to_class (gap `All (Size.rem 1.0)));
149 Flexbox.(to_class (justify `Center));
150 ])] [
151 (* Hover color change *)
152 El.button ~at:[classes_attr (tw [
153 Color.bg (Color.make `Blue ~variant:`V500 ());
154 Color.text Color.white;
155 Spacing.(to_class (px (Size.rem 1.5)));
156 Spacing.(to_class (py (Size.rem 0.75)));
157 Effects.rounded_md;
158 Typography.(to_class (font_weight `Medium));
159 Effects.transition `All;
160 Variants.hover (Color.bg (Color.make `Blue ~variant:`V600 ()));
161 ])] [El.txt "Hover Color"];
162
163 (* Hover shadow *)
164 El.button ~at:[classes_attr (tw [
165 Color.bg (Color.make `Green ~variant:`V500 ());
166 Color.text Color.white;
167 Spacing.(to_class (px (Size.rem 1.5)));
168 Spacing.(to_class (py (Size.rem 0.75)));
169 Effects.rounded_md;
170 Typography.(to_class (font_weight `Medium));
171 Effects.shadow_md;
172 Effects.transition `All;
173 Variants.hover Effects.shadow_lg;
174 ])] [El.txt "Hover Shadow"];
175
176 (* Scale effect *)
177 El.button ~at:[classes_attr (tw [
178 Color.bg (Color.make `Purple ~variant:`V500 ());
179 Color.text Color.white;
180 Spacing.(to_class (px (Size.rem 1.5)));
181 Spacing.(to_class (py (Size.rem 0.75)));
182 Effects.rounded_md;
183 Typography.(to_class (font_weight `Medium));
184 Effects.transition `All;
185 ]); At.class' "hover:scale-105 active:scale-95"] [El.txt "Scale Effect"];
186
187 (* Focus ring *)
188 El.button ~at:[classes_attr (tw [
189 Color.bg (Color.make `Red ~variant:`V500 ());
190 Color.text Color.white;
191 Spacing.(to_class (px (Size.rem 1.5)));
192 Spacing.(to_class (py (Size.rem 0.75)));
193 Effects.rounded_md;
194 Typography.(to_class (font_weight `Medium));
195 Effects.transition `All;
196 Variants.focus Effects.shadow_md;
197 ])] [El.txt "Focus Ring"];
198 ];
199 ];
200
201 (* Card Hover Effects *)
202 El.section ~at:[At.class' "mb-8"] [
203 El.h2 ~at:[classes_attr (tw [
204 Typography.(to_class (font_size `Xl));
205 Typography.(to_class (font_weight `Semibold));
206 Color.text (Color.make `Gray ~variant:`V700 ());
207 ]); At.class' "mb-6"] [El.txt "Card Hover Effects"];
208
209 El.div ~at:[classes_attr (tw [
210 Display.grid;
211 Grid.(to_class (template_cols (`Cols 1)));
212 Responsive.(to_class (at_breakpoint `Md (Grid.(to_class (template_cols (`Cols 2))))));
213 Spacing.(to_class (gap `All (Size.rem 1.5)));
214 ])] [
215 (* Hover shadow card *)
216 El.div ~at:[classes_attr (tw [
217 Color.bg Color.white;
218 Spacing.(to_class (p (Size.rem 1.5)));
219 Effects.rounded_lg;
220 Effects.shadow_md;
221 Effects.transition `All;
222 Variants.hover Effects.shadow_lg;
223 ]); At.class' "cursor-pointer"] [
224 El.h3 ~at:[classes_attr (tw [
225 Typography.(to_class (font_size `Lg));
226 Typography.(to_class (font_weight `Semibold));
227 Color.text (Color.make `Gray ~variant:`V800 ());
228 ]); At.class' "mb-2"] [El.txt "Shadow Lift"];
229 El.p ~at:[classes_attr (tw [
230 Color.text (Color.make `Gray ~variant:`V600 ());
231 ])] [El.txt "Hover to see the shadow increase. This creates a lifting effect."];
232 ];
233
234 (* Scale and shadow card *)
235 El.div ~at:[classes_attr (tw [
236 Color.bg Color.white;
237 Spacing.(to_class (p (Size.rem 1.5)));
238 Effects.rounded_lg;
239 Effects.shadow_md;
240 Effects.transition `All;
241 ]); At.class' "cursor-pointer hover:scale-105 hover:shadow-xl"] [
242 El.h3 ~at:[classes_attr (tw [
243 Typography.(to_class (font_size `Lg));
244 Typography.(to_class (font_weight `Semibold));
245 Color.text (Color.make `Gray ~variant:`V800 ());
246 ]); At.class' "mb-2"] [El.txt "Scale + Shadow"];
247 El.p ~at:[classes_attr (tw [
248 Color.text (Color.make `Gray ~variant:`V600 ());
249 ])] [El.txt "This card both scales up and increases shadow on hover."];
250 ];
251 ];
252 ];
253
254 (* Border Effects *)
255 El.section [
256 El.h2 ~at:[classes_attr (tw [
257 Typography.(to_class (font_size `Xl));
258 Typography.(to_class (font_weight `Semibold));
259 Color.text (Color.make `Gray ~variant:`V700 ());
260 ]); At.class' "mb-6"] [El.txt "Border Effects"];
261
262 El.div ~at:[classes_attr (tw [
263 Display.grid;
264 Grid.(to_class (template_cols (`Cols 1)));
265 Responsive.(to_class (at_breakpoint `Md (Grid.(to_class (template_cols (`Cols 3))))));
266 Spacing.(to_class (gap `All (Size.rem 1.5)));
267 ])] [
268 (* Regular border *)
269 El.div ~at:[classes_attr (tw [
270 Color.bg Color.white;
271 Spacing.(to_class (p (Size.rem 1.5)));
272 Effects.border;
273 Color.border (Color.make `Gray ~variant:`V200 ());
274 Effects.rounded_lg;
275 ]); At.class' "text-center"] [
276 El.h3 ~at:[classes_attr (tw [
277 Typography.(to_class (font_weight `Semibold));
278 Color.text (Color.make `Gray ~variant:`V700 ());
279 ]); At.class' "mb-2"] [El.txt "Regular Border"];
280 El.p ~at:[classes_attr (tw [
281 Typography.(to_class (font_size `Sm));
282 Color.text (Color.make `Gray ~variant:`V600 ());
283 ])] [El.txt "border border-gray-200"];
284 ];
285
286 (* Colored border *)
287 El.div ~at:[classes_attr (tw [
288 Color.bg Color.white;
289 Spacing.(to_class (p (Size.rem 1.5)));
290 Effects.border;
291 Color.border (Color.make `Blue ~variant:`V300 ());
292 Effects.rounded_lg;
293 ]); At.class' "text-center"] [
294 El.h3 ~at:[classes_attr (tw [
295 Typography.(to_class (font_weight `Semibold));
296 Color.text (Color.make `Blue ~variant:`V600 ());
297 ]); At.class' "mb-2"] [El.txt "Colored Border"];
298 El.p ~at:[classes_attr (tw [
299 Typography.(to_class (font_size `Sm));
300 Color.text (Color.make `Gray ~variant:`V600 ());
301 ])] [El.txt "border border-blue-300"];
302 ];
303
304 (* Thick border *)
305 El.div ~at:[At.class' "bg-white p-6 border-2 border-purple-300 rounded-lg text-center"] [
306 El.h3 ~at:[classes_attr (tw [
307 Typography.(to_class (font_weight `Semibold));
308 Color.text (Color.make `Purple ~variant:`V600 ());
309 ]); At.class' "mb-2"] [El.txt "Thick Border"];
310 El.p ~at:[classes_attr (tw [
311 Typography.(to_class (font_size `Sm));
312 Color.text (Color.make `Gray ~variant:`V600 ());
313 ])] [El.txt "border-2 border-purple-300"];
314 ];
315 ];
316 ];
317 ];
318 ];
319 ] in
320 html_doc
321
322let () =
323 (* Output HTML to stdout *)
324 let html_doc = create_effects_demo () in
325 let html_string = El.to_string ~doctype:true html_doc in
326 print_string html_string