···
1
-
(* Main module for Tailwind HTML library *)
1
+
(* GADT-based Tailwind HTML library with heterogeneous lists *)
3
-
(* Common utility for converting Tailwind classes to HTML class attribute *)
4
-
let classes_attr tailwind_classes =
5
-
Htmlit.At.class' (Tailwind.to_string tailwind_classes)
3
+
(* Color utilities *)
4
+
let blue variant = Tailwind.Color.make `Blue ~variant:(match variant with
5
+
| 50 -> `V50 | 100 -> `V100 | 200 -> `V200 | 300 -> `V300 | 400 -> `V400
6
+
| 500 -> `V500 | 600 -> `V600 | 700 -> `V700 | 800 -> `V800 | 900 -> `V900
7
-
(* Apply Tailwind classes to an existing HTML element by wrapping it *)
8
-
let with_classes classes element =
10
-
El.span ~at:[classes_attr classes] [element]
9
+
let gray variant = Tailwind.Color.make `Gray ~variant:(match variant with
10
+
| 50 -> `V50 | 100 -> `V100 | 200 -> `V200 | 300 -> `V300 | 400 -> `V400
11
+
| 500 -> `V500 | 600 -> `V600 | 700 -> `V700 | 800 -> `V800 | 900 -> `V900
12
-
(* Conditionally apply Tailwind classes *)
13
-
let with_classes_if condition classes element =
14
-
if condition then with_classes classes element else element
14
+
let red variant = Tailwind.Color.make `Red ~variant:(match variant with
15
+
| 50 -> `V50 | 100 -> `V100 | 200 -> `V200 | 300 -> `V300 | 400 -> `V400
16
+
| 500 -> `V500 | 600 -> `V600 | 700 -> `V700 | 800 -> `V800 | 900 -> `V900
16
-
(* Create an element with Tailwind classes and optional attributes *)
17
-
let el tag ?classes ?attributes children =
19
-
let base_attrs = match classes with
20
-
| Some c -> [classes_attr c]
23
-
let custom_attrs = match attributes with
24
-
| Some attrs -> List.map (fun (k, v) -> At.v k v) attrs
27
-
let all_attrs = base_attrs @ custom_attrs in
28
-
El.v tag ~at:all_attrs children
19
+
let green variant = Tailwind.Color.make `Green ~variant:(match variant with
20
+
| 50 -> `V50 | 100 -> `V100 | 200 -> `V200 | 300 -> `V300 | 400 -> `V400
21
+
| 500 -> `V500 | 600 -> `V600 | 700 -> `V700 | 800 -> `V800 | 900 -> `V900
30
-
(* Common HTML elements with Tailwind class support *)
31
-
let div ?classes ?attributes children = el "div" ?classes ?attributes children
32
-
let span ?classes ?attributes children = el "span" ?classes ?attributes children
33
-
let p ?classes ?attributes children = el "p" ?classes ?attributes children
34
-
let a ?classes ?attributes ~href children =
35
-
let attrs = match attributes with Some a -> a | None -> [] in
36
-
el "a" ?classes ~attributes:(("href", href) :: attrs) children
37
-
let img ?classes ?attributes ~src ~alt () =
38
-
let attrs = match attributes with Some a -> a | None -> [] in
39
-
el "img" ?classes ~attributes:(("src", src) :: ("alt", alt) :: attrs) []
40
-
let ul ?classes ?attributes children = el "ul" ?classes ?attributes children
41
-
let ol ?classes ?attributes children = el "ol" ?classes ?attributes children
42
-
let li ?classes ?attributes children = el "li" ?classes ?attributes children
44
-
(* Utility functions for colors and sizes *)
45
-
let blue variant = Tailwind.Color.make `Blue ~variant:(match variant with
24
+
let yellow variant = Tailwind.Color.make `Yellow ~variant:(match variant with
| 50 -> `V50 | 100 -> `V100 | 200 -> `V200 | 300 -> `V300 | 400 -> `V400
| 500 -> `V500 | 600 -> `V600 | 700 -> `V700 | 800 -> `V800 | 900 -> `V900
50
-
let gray variant = Tailwind.Color.make `Gray ~variant:(match variant with
29
+
let indigo variant = Tailwind.Color.make `Indigo ~variant:(match variant with
| 50 -> `V50 | 100 -> `V100 | 200 -> `V200 | 300 -> `V300 | 400 -> `V400
| 500 -> `V500 | 600 -> `V600 | 700 -> `V700 | 800 -> `V800 | 900 -> `V900
55
-
let red variant = Tailwind.Color.make `Red ~variant:(match variant with
34
+
let purple variant = Tailwind.Color.make `Purple ~variant:(match variant with
| 50 -> `V50 | 100 -> `V100 | 200 -> `V200 | 300 -> `V300 | 400 -> `V400
| 500 -> `V500 | 600 -> `V600 | 700 -> `V700 | 800 -> `V800 | 900 -> `V900
60
-
let green variant = Tailwind.Color.make `Green ~variant:(match variant with
39
+
let pink variant = Tailwind.Color.make `Pink ~variant:(match variant with
| 50 -> `V50 | 100 -> `V100 | 200 -> `V200 | 300 -> `V300 | 400 -> `V400
| 500 -> `V500 | 600 -> `V600 | 700 -> `V700 | 800 -> `V800 | 900 -> `V900
···
let screen = Tailwind.Size.screen
let txt s = Htmlit.El.txt s
73
-
(* Common utility classes *)
74
-
let flex = Tailwind.Display.flex
75
-
let flex_col = Tailwind.Flexbox.(to_class (direction `Col))
76
-
let items_center = Tailwind.Flexbox.(to_class (align_items `Center))
77
-
let justify_center = Tailwind.Flexbox.(to_class (justify `Center))
78
-
let justify_between = Tailwind.Flexbox.(to_class (justify `Between))
79
-
let font_bold = Tailwind.Typography.(to_class (font_weight `Bold))
80
-
let font_semibold = Tailwind.Typography.(to_class (font_weight `Semibold))
81
-
let text_center = Tailwind.Typography.(to_class (text_align `Center))
82
-
let w_full = Tailwind.Layout.w_full
83
-
let h_full = Tailwind.Layout.h_full
84
-
let rounded_lg = Tailwind.Effects.rounded_lg
85
-
let rounded_md = Tailwind.Effects.rounded_md
86
-
let shadow_md = Tailwind.Effects.shadow_md
87
-
let shadow_lg = Tailwind.Effects.shadow_lg
52
+
(* GADT for Tailwind properties with types indicating their category *)
54
+
| Text_color : Tailwind.Color.t -> [`Text_color] tw_prop
55
+
| Bg_color : Tailwind.Color.t -> [`Bg_color] tw_prop
56
+
| Font_size : Tailwind.Typography.font_size -> [`Font_size] tw_prop
57
+
| Font_weight : Tailwind.Typography.font_weight -> [`Font_weight] tw_prop
58
+
| Margin : Tailwind.Size.t -> [`Margin] tw_prop
59
+
| Margin_x : Tailwind.Size.t -> [`Margin] tw_prop
60
+
| Margin_y : Tailwind.Size.t -> [`Margin] tw_prop
61
+
| Margin_top : Tailwind.Size.t -> [`Margin] tw_prop
62
+
| Margin_bottom : Tailwind.Size.t -> [`Margin] tw_prop
63
+
| Margin_left : Tailwind.Size.t -> [`Margin] tw_prop
64
+
| Margin_right : Tailwind.Size.t -> [`Margin] tw_prop
65
+
| Padding : Tailwind.Size.t -> [`Padding] tw_prop
66
+
| Padding_x : Tailwind.Size.t -> [`Padding] tw_prop
67
+
| Padding_y : Tailwind.Size.t -> [`Padding] tw_prop
68
+
| Width : Tailwind.Size.t -> [`Width] tw_prop
69
+
| Height : Tailwind.Size.t -> [`Height] tw_prop
70
+
| Max_width : Tailwind.Size.t -> [`Width] tw_prop
71
+
| Min_height : Tailwind.Size.t -> [`Height] tw_prop
72
+
| Display_flex : [`Layout] tw_prop
73
+
| Display_block : [`Layout] tw_prop
74
+
| Display_inline : [`Layout] tw_prop
75
+
| Display_inline_block : [`Layout] tw_prop
76
+
| Items_center : [`Layout] tw_prop
77
+
| Items_start : [`Layout] tw_prop
78
+
| Items_end : [`Layout] tw_prop
79
+
| Justify_center : [`Layout] tw_prop
80
+
| Justify_between : [`Layout] tw_prop
81
+
| Justify_start : [`Layout] tw_prop
82
+
| Justify_end : [`Layout] tw_prop
83
+
| Flex_col : [`Layout] tw_prop
84
+
| Flex_row : [`Layout] tw_prop
85
+
| Text_center : [`Layout] tw_prop
86
+
| Text_left : [`Layout] tw_prop
87
+
| Text_right : [`Layout] tw_prop
88
+
| Rounded : [< `Sm | `Md | `Lg | `Full ] -> [`Effects] tw_prop
89
+
| Shadow : [< `Sm | `Md | `Lg ] -> [`Effects] tw_prop
90
+
| Border : [`Effects] tw_prop
91
+
| Border_color : Tailwind.Color.t -> [`Effects] tw_prop
92
+
| Transition : [`Effects] tw_prop
94
+
(* Heterogeneous list *)
95
+
type tw_list = tw_list_item list
96
+
and tw_list_item = Any : 'a tw_prop -> tw_list_item
98
+
(* Convert GADT properties to Tailwind classes *)
99
+
let to_tailwind_classes (props : tw_list) : Tailwind.t list =
100
+
let convert_prop : type a. a tw_prop -> Tailwind.t = function
101
+
| Text_color color -> Tailwind.Color.text color
102
+
| Bg_color color -> Tailwind.Color.bg color
103
+
| Font_size size -> Tailwind.Typography.(to_class (font_size size))
104
+
| Font_weight weight -> Tailwind.Typography.(to_class (font_weight weight))
105
+
| Margin size -> Tailwind.Spacing.(to_class (m size))
106
+
| Margin_x size -> Tailwind.Spacing.(to_class (mx size))
107
+
| Margin_y size -> Tailwind.Spacing.(to_class (my size))
108
+
| Margin_top size -> Tailwind.Spacing.(to_class (mt size))
109
+
| Margin_bottom size -> Tailwind.Spacing.(to_class (mb size))
110
+
| Margin_left size -> Tailwind.Spacing.(to_class (ml size))
111
+
| Margin_right size -> Tailwind.Spacing.(to_class (mr size))
112
+
| Padding size -> Tailwind.Spacing.(to_class (p size))
113
+
| Padding_x size -> Tailwind.Spacing.(to_class (px size))
114
+
| Padding_y size -> Tailwind.Spacing.(to_class (py size))
115
+
| Width size -> Tailwind.Layout.(to_class (width size))
116
+
| Height size -> Tailwind.Layout.(to_class (height size))
117
+
| Max_width size -> Tailwind.Layout.(to_class (max_width size))
118
+
| Min_height size -> Tailwind.Layout.(to_class (min_height size))
119
+
| Display_flex -> Tailwind.Display.flex
120
+
| Display_block -> Tailwind.Display.block
121
+
| Display_inline -> Tailwind.Display.inline
122
+
| Display_inline_block -> Tailwind.Display.inline_block
123
+
| Items_center -> Tailwind.Flexbox.(to_class (align_items `Center))
124
+
| Items_start -> Tailwind.Flexbox.(to_class (align_items `Start))
125
+
| Items_end -> Tailwind.Flexbox.(to_class (align_items `End))
126
+
| Justify_center -> Tailwind.Flexbox.(to_class (justify `Center))
127
+
| Justify_between -> Tailwind.Flexbox.(to_class (justify `Between))
128
+
| Justify_start -> Tailwind.Flexbox.(to_class (justify `Start))
129
+
| Justify_end -> Tailwind.Flexbox.(to_class (justify `End))
130
+
| Flex_col -> Tailwind.Flexbox.(to_class (direction `Col))
131
+
| Flex_row -> Tailwind.Flexbox.(to_class (direction `Row))
132
+
| Text_center -> Tailwind.Typography.(to_class (text_align `Center))
133
+
| Text_left -> Tailwind.Typography.(to_class (text_align `Left))
134
+
| Text_right -> Tailwind.Typography.(to_class (text_align `Right))
135
+
| Rounded radius ->
137
+
| `Sm -> Tailwind.Effects.rounded_sm
138
+
| `Md -> Tailwind.Effects.rounded_md
139
+
| `Lg -> Tailwind.Effects.rounded_lg
140
+
| `Full -> Tailwind.Effects.rounded_full)
143
+
| `Sm -> Tailwind.Effects.shadow_sm
144
+
| `Md -> Tailwind.Effects.shadow_md
145
+
| `Lg -> Tailwind.Effects.shadow_lg)
146
+
| Border -> Tailwind.Effects.border
147
+
| Border_color color -> Tailwind.Color.border color
148
+
| Transition -> Tailwind.Effects.transition `All
150
+
List.map (fun (Any prop) -> convert_prop prop) props
152
+
(* Convert heterogeneous list to Tailwind.t *)
154
+
Tailwind.Css.tw (to_tailwind_classes props)
156
+
(* Helper for HTML class attribute *)
157
+
let classes_attr props =
158
+
Htmlit.At.class' (Tailwind.to_string (styles props))
160
+
(* Helper constructors for convenient usage *)
161
+
let text_color c = Any (Text_color c)
162
+
let bg_color c = Any (Bg_color c)
163
+
let font_size s = Any (Font_size s)
164
+
let font_weight w = Any (Font_weight w)
165
+
let margin s = Any (Margin s)
166
+
let margin_x s = Any (Margin_x s)
167
+
let margin_y s = Any (Margin_y s)
168
+
let margin_top s = Any (Margin_top s)
169
+
let margin_bottom s = Any (Margin_bottom s)
170
+
let margin_left s = Any (Margin_left s)
171
+
let margin_right s = Any (Margin_right s)
172
+
let padding s = Any (Padding s)
173
+
let padding_x s = Any (Padding_x s)
174
+
let padding_y s = Any (Padding_y s)
175
+
let width s = Any (Width s)
176
+
let height s = Any (Height s)
177
+
let max_width s = Any (Max_width s)
178
+
let min_height s = Any (Min_height s)
179
+
let flex = Any Display_flex
180
+
let block = Any Display_block
181
+
let inline = Any Display_inline
182
+
let inline_block = Any Display_inline_block
183
+
let items_center = Any Items_center
184
+
let items_start = Any Items_start
185
+
let items_end = Any Items_end
186
+
let justify_center = Any Justify_center
187
+
let justify_between = Any Justify_between
188
+
let justify_start = Any Justify_start
189
+
let justify_end = Any Justify_end
190
+
let flex_col = Any Flex_col
191
+
let flex_row = Any Flex_row
192
+
let text_center = Any Text_center
193
+
let text_left = Any Text_left
194
+
let text_right = Any Text_right
195
+
let rounded r = Any (Rounded r)
196
+
let shadow s = Any (Shadow s)
197
+
let border = Any Border
198
+
let border_color c = Any (Border_color c)
199
+
let transition = Any Transition
201
+
(* GADT-based element functions *)
202
+
let h1 ?styles children =
203
+
let attrs = match styles with
204
+
| Some s -> [classes_attr s]
207
+
Htmlit.El.h1 ~at:attrs children
209
+
let h2 ?styles children =
210
+
let attrs = match styles with
211
+
| Some s -> [classes_attr s]
214
+
Htmlit.El.h2 ~at:attrs children
216
+
let h3 ?styles children =
217
+
let attrs = match styles with
218
+
| Some s -> [classes_attr s]
221
+
Htmlit.El.h3 ~at:attrs children
223
+
let h4 ?styles children =
224
+
let attrs = match styles with
225
+
| Some s -> [classes_attr s]
228
+
Htmlit.El.h4 ~at:attrs children
230
+
let h5 ?styles children =
231
+
let attrs = match styles with
232
+
| Some s -> [classes_attr s]
235
+
Htmlit.El.h5 ~at:attrs children
237
+
let h6 ?styles children =
238
+
let attrs = match styles with
239
+
| Some s -> [classes_attr s]
242
+
Htmlit.El.h6 ~at:attrs children
244
+
let p ?styles children =
245
+
let attrs = match styles with
246
+
| Some s -> [classes_attr s]
249
+
Htmlit.El.p ~at:attrs children
251
+
let div ?styles children =
252
+
let attrs = match styles with
253
+
| Some s -> [classes_attr s]
256
+
Htmlit.El.div ~at:attrs children
89
-
(* Enhanced element functions with styling parameters *)
90
-
let h1 ?size ?weight ?color ?align ?mb ?classes children =
91
-
let base_styles = [Tailwind.Typography.(to_class (font_size `Xl2)); font_bold] in
92
-
let size_styles = match size with
93
-
| Some `Xl -> [Tailwind.Typography.(to_class (font_size `Xl))]
94
-
| Some `Xl2 -> [Tailwind.Typography.(to_class (font_size `Xl2))]
95
-
| Some `Xl3 -> [Tailwind.Typography.(to_class (font_size `Xl3))]
96
-
| Some `Xl4 -> [Tailwind.Typography.(to_class (font_size `Xl4))]
258
+
let span ?styles children =
259
+
let attrs = match styles with
260
+
| Some s -> [classes_attr s]
99
-
let weight_styles = match weight with
100
-
| Some `Bold -> [font_bold]
101
-
| Some `Semibold -> [font_semibold]
102
-
| Some `Medium -> [Tailwind.Typography.(to_class (font_weight `Medium))]
263
+
Htmlit.El.span ~at:attrs children
265
+
let button ?styles children =
266
+
let attrs = match styles with
267
+
| Some s -> [classes_attr s]
105
-
let color_styles = match color with Some c -> [Tailwind.Color.text c] | None -> [] in
106
-
let align_styles = match align with
107
-
| Some `Center -> [text_center]
108
-
| Some `Left -> [Tailwind.Typography.(to_class (text_align `Left))]
109
-
| Some `Right -> [Tailwind.Typography.(to_class (text_align `Right))]
270
+
Htmlit.El.button ~at:attrs children
272
+
let a ?styles ~href children =
273
+
let attrs = [Htmlit.At.href href] @ (match styles with
274
+
| Some s -> [classes_attr s]
277
+
Htmlit.El.a ~at:attrs children
279
+
let img ?styles ~src ~alt () =
280
+
let attrs = [Htmlit.At.src src; Htmlit.At.alt alt] @ (match styles with
281
+
| Some s -> [classes_attr s]
284
+
Htmlit.El.img ~at:attrs ()
286
+
let ul ?styles children =
287
+
let attrs = match styles with
288
+
| Some s -> [classes_attr s]
112
-
let spacing_styles = match mb with Some s -> [Tailwind.Spacing.(to_class (mb s))] | None -> [] in
113
-
let final_classes = Tailwind.Css.tw (base_styles @ size_styles @ weight_styles @ color_styles @ align_styles @ spacing_styles @
114
-
(match classes with Some c -> [c] | None -> [])) in
115
-
Htmlit.El.h1 ~at:[classes_attr final_classes] children
291
+
Htmlit.El.ul ~at:attrs children
117
-
let h2 ?size ?weight ?color ?align ?mb ?classes children =
118
-
let base_styles = [Tailwind.Typography.(to_class (font_size `Xl)); font_semibold] in
119
-
let size_styles = match size with
120
-
| Some `Lg -> [Tailwind.Typography.(to_class (font_size `Lg))]
121
-
| Some `Xl -> [Tailwind.Typography.(to_class (font_size `Xl))]
122
-
| Some `Xl2 -> [Tailwind.Typography.(to_class (font_size `Xl2))]
293
+
let ol ?styles children =
294
+
let attrs = match styles with
295
+
| Some s -> [classes_attr s]
125
-
let weight_styles = match weight with
126
-
| Some `Bold -> [font_bold]
127
-
| Some `Semibold -> [font_semibold]
128
-
| Some `Medium -> [Tailwind.Typography.(to_class (font_weight `Medium))]
298
+
Htmlit.El.ol ~at:attrs children
300
+
let li ?styles children =
301
+
let attrs = match styles with
302
+
| Some s -> [classes_attr s]
131
-
let color_styles = match color with Some c -> [Tailwind.Color.text c] | None -> [] in
132
-
let align_styles = match align with
133
-
| Some `Center -> [text_center]
134
-
| Some `Left -> [Tailwind.Typography.(to_class (text_align `Left))]
135
-
| Some `Right -> [Tailwind.Typography.(to_class (text_align `Right))]
305
+
Htmlit.El.li ~at:attrs children
307
+
let section ?styles children =
308
+
let attrs = match styles with
309
+
| Some s -> [classes_attr s]
138
-
let spacing_styles = match mb with Some s -> [Tailwind.Spacing.(to_class (mb s))] | None -> [] in
139
-
let final_classes = Tailwind.Css.tw (base_styles @ size_styles @ weight_styles @ color_styles @ align_styles @ spacing_styles @
140
-
(match classes with Some c -> [c] | None -> [])) in
141
-
Htmlit.El.h2 ~at:[classes_attr final_classes] children
312
+
Htmlit.El.section ~at:attrs children
143
-
let p_styled ?size ?color ?align ?mb ?classes children =
144
-
let base_styles = [Tailwind.Typography.(to_class (font_size `Base))] in
145
-
let size_styles = match size with
146
-
| Some `Sm -> [Tailwind.Typography.(to_class (font_size `Sm))]
147
-
| Some `Base -> [Tailwind.Typography.(to_class (font_size `Base))]
148
-
| Some `Lg -> [Tailwind.Typography.(to_class (font_size `Lg))]
314
+
let article ?styles children =
315
+
let attrs = match styles with
316
+
| Some s -> [classes_attr s]
151
-
let color_styles = match color with Some c -> [Tailwind.Color.text c] | None -> [] in
152
-
let align_styles = match align with
153
-
| Some `Center -> [text_center]
154
-
| Some `Left -> [Tailwind.Typography.(to_class (text_align `Left))]
155
-
| Some `Right -> [Tailwind.Typography.(to_class (text_align `Right))]
319
+
Htmlit.El.article ~at:attrs children
321
+
let nav ?styles children =
322
+
let attrs = match styles with
323
+
| Some s -> [classes_attr s]
158
-
let spacing_styles = match mb with Some s -> [Tailwind.Spacing.(to_class (mb s))] | None -> [] in
159
-
let final_classes = Tailwind.Css.tw (base_styles @ size_styles @ color_styles @ align_styles @ spacing_styles @
160
-
(match classes with Some c -> [c] | None -> [])) in
161
-
Htmlit.El.p ~at:[classes_attr final_classes] children
326
+
Htmlit.El.nav ~at:attrs children
163
-
(* Simple component functions *)
328
+
let header ?styles children =
329
+
let attrs = match styles with
330
+
| Some s -> [classes_attr s]
333
+
Htmlit.El.header ~at:attrs children
335
+
let footer ?styles children =
336
+
let attrs = match styles with
337
+
| Some s -> [classes_attr s]
340
+
Htmlit.El.footer ~at:attrs children
342
+
let main ?styles children =
343
+
let attrs = match styles with
344
+
| Some s -> [classes_attr s]
347
+
Htmlit.El.main ~at:attrs children
349
+
(* Pre-built component helpers *)
165
-
let container_classes = Tailwind.Css.tw [Tailwind.Patterns.container ()] in
166
-
div ~classes:container_classes children
352
+
max_width (Tailwind.Size.rem 80.0);
354
+
padding_x (rem 1.0);
let flex_center children =
169
-
let flex_classes = Tailwind.Css.tw [flex; items_center; justify_center] in
170
-
div ~classes:flex_classes children
358
+
div ~styles:[flex; items_center; justify_center] children
172
-
let card ?elevated ?padding children =
173
-
let base_classes = [Tailwind.Color.bg Tailwind.Color.white; rounded_lg] in
174
-
let shadow_classes = if elevated = Some true then [shadow_lg] else [Tailwind.Effects.shadow_sm] in
175
-
let padding_classes = if padding <> Some false then [Tailwind.Spacing.(to_class (p (rem 1.5)))] else [] in
176
-
let card_classes = Tailwind.Css.tw (base_classes @ shadow_classes @ padding_classes) in
177
-
div ~classes:card_classes children
360
+
let card ?elevated children =
361
+
let shadow_style = if elevated = Some true then [shadow `Lg] else [shadow `Md] in
363
+
bg_color (Tailwind.Color.white);
366
+
] @ shadow_style) children
179
-
let btn_primary ?size ?disabled children =
180
-
let base_classes = [
181
-
flex; items_center; justify_center; rounded_md;
182
-
Tailwind.Typography.(to_class (font_size `Sm));
183
-
Tailwind.Typography.(to_class (font_weight `Medium));
184
-
Tailwind.Color.bg (blue 600);
185
-
Tailwind.Color.text Tailwind.Color.white;
186
-
Tailwind.Variants.hover (Tailwind.Color.bg (blue 700));
187
-
Tailwind.Effects.transition `Colors;
189
-
let size_classes = match size with
190
-
| Some `Sm -> [Tailwind.Spacing.(to_class (px (rem 0.75))); Tailwind.Spacing.(to_class (py (rem 0.375)))]
191
-
| Some `Lg -> [Tailwind.Spacing.(to_class (px (rem 2.0))); Tailwind.Spacing.(to_class (py (rem 0.75)))]
192
-
| _ -> [Tailwind.Spacing.(to_class (px (rem 1.0))); Tailwind.Spacing.(to_class (py (rem 0.5)))]
368
+
let btn_primary ?size children =
369
+
let size_styles = match size with
370
+
| Some `Sm -> [padding_x (rem 0.75); padding_y (rem 0.375); font_size `Sm]
371
+
| Some `Lg -> [padding_x (rem 2.0); padding_y (rem 0.75); font_size `Base]
372
+
| _ -> [padding_x (rem 1.0); padding_y (rem 0.5); font_size `Sm]
194
-
let disabled_classes = if disabled = Some true then [
195
-
Tailwind.Css.make "disabled:opacity-50";
196
-
Tailwind.Css.make "disabled:cursor-not-allowed"
198
-
let btn_classes = Tailwind.Css.tw (base_classes @ size_classes @ disabled_classes) in
199
-
let attrs = [classes_attr btn_classes] @ (if disabled = Some true then [Htmlit.At.disabled] else []) in
200
-
Htmlit.El.button ~at:attrs children
375
+
bg_color (blue 600);
376
+
text_color (Tailwind.Color.white);
377
+
font_weight `Medium;
380
+
] @ size_styles) children
202
-
let btn_secondary ?size ?disabled children =
203
-
let base_classes = [
204
-
flex; items_center; justify_center; rounded_md;
205
-
Tailwind.Typography.(to_class (font_size `Sm));
206
-
Tailwind.Typography.(to_class (font_weight `Medium));
207
-
Tailwind.Color.bg (gray 200);
208
-
Tailwind.Color.text (gray 900);
209
-
Tailwind.Variants.hover (Tailwind.Color.bg (gray 300));
210
-
Tailwind.Effects.transition `Colors;
212
-
let size_classes = match size with
213
-
| Some `Sm -> [Tailwind.Spacing.(to_class (px (rem 0.75))); Tailwind.Spacing.(to_class (py (rem 0.375)))]
214
-
| Some `Lg -> [Tailwind.Spacing.(to_class (px (rem 2.0))); Tailwind.Spacing.(to_class (py (rem 0.75)))]
215
-
| _ -> [Tailwind.Spacing.(to_class (px (rem 1.0))); Tailwind.Spacing.(to_class (py (rem 0.5)))]
382
+
let btn_secondary ?size children =
383
+
let size_styles = match size with
384
+
| Some `Sm -> [padding_x (rem 0.75); padding_y (rem 0.375); font_size `Sm]
385
+
| Some `Lg -> [padding_x (rem 2.0); padding_y (rem 0.75); font_size `Base]
386
+
| _ -> [padding_x (rem 1.0); padding_y (rem 0.5); font_size `Sm]
217
-
let disabled_classes = if disabled = Some true then [
218
-
Tailwind.Css.make "disabled:opacity-50";
219
-
Tailwind.Css.make "disabled:cursor-not-allowed"
221
-
let btn_classes = Tailwind.Css.tw (base_classes @ size_classes @ disabled_classes) in
222
-
let attrs = [classes_attr btn_classes] @ (if disabled = Some true then [Htmlit.At.disabled] else []) in
223
-
Htmlit.El.button ~at:attrs children
389
+
bg_color (gray 200);
390
+
text_color (gray 900);
391
+
font_weight `Medium;
394
+
] @ size_styles) children
225
-
(* Text element with built-in typography utilities *)
226
-
let text ?size ?weight ?color ?align ?classes text_content =
227
-
let base_styles = [] in
228
-
let size_styles = match size with Some s -> [Tailwind.Typography.(to_class (font_size s))] | None -> [] in
229
-
let weight_styles = match weight with Some w -> [Tailwind.Typography.(to_class (font_weight w))] | None -> [] in
230
-
let color_styles = match color with Some c -> [Tailwind.Color.text c] | None -> [] in
231
-
let align_styles = match align with Some a -> [Tailwind.Typography.(to_class (text_align a))] | None -> [] in
232
-
let text_classes = Tailwind.Css.tw (base_styles @ size_styles @ weight_styles @ color_styles @ align_styles) in
233
-
let final_classes = match classes with
234
-
| Some c -> Tailwind.Css.tw [text_classes; c]
235
-
| None -> text_classes
396
+
let btn_outline ?size children =
397
+
let size_styles = match size with
398
+
| Some `Sm -> [padding_x (rem 0.75); padding_y (rem 0.375); font_size `Sm]
399
+
| Some `Lg -> [padding_x (rem 2.0); padding_y (rem 0.75); font_size `Base]
400
+
| _ -> [padding_x (rem 1.0); padding_y (rem 0.5); font_size `Sm]
237
-
span ~classes:final_classes [Htmlit.El.txt text_content]
403
+
bg_color (Tailwind.Color.transparent);
404
+
text_color (gray 700);
405
+
font_weight `Medium;
408
+
border_color (gray 300);
410
+
] @ size_styles) children