Tailwind classes in OCaml

Update README to showcase GADT-based Tailwind_html interface

- Rewrite README to focus on the new GADT heterogeneous list interface
- Add comprehensive examples from layout_and_spacing_03.ml and other demos
- Showcase CSS Grid support, built-in components, and type safety benefits
- Include detailed API reference for all GADT property categories
- Update installation and getting started sections for the new interface
- Remove outdated verbose Tailwind syntax examples in favor of succinct GADT syntax

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

Changed files
+276 -148
+276 -148
README.md
···
# Tailwind OCaml
-
An OCaml library for generating Tailwind CSS classes with compile-time
-
validation and a companion HTML generation library using Htmlit.
+
Type-safe Tailwind CSS generation for OCaml with a revolutionary GADT-based interface for succinct, compile-time validated styling.
This project provides two main libraries:
- **`tailwind`**: Core library for type-safe Tailwind CSS class generation
-
- **`tailwind-html`**: HTML component library built on top of [Htmlit](https://github.com/dbuenzli/htmlit)
+
- **`tailwind-html`**: High-level HTML component library with GADT-based heterogeneous list interface built on [Htmlit](https://github.com/dbuenzli/htmlit)
## Features
-
- Compile-time validation of Tailwind classes
-
- Type-safe color variants and sizes
-
- Exhaustive pattern matching for all utility classes
+
- **GADT-based Interface**: Succinct heterogeneous list syntax with compile-time type safety
+
- **Zero Runtime Cost**: All CSS generation happens at compile time
+
- **Comprehensive Grid Support**: Full CSS Grid integration with type-safe properties
+
- **Type-Safe Colors & Spacing**: Exhaustive variants with compile-time validation
+
- **Built-in Components**: Pre-styled buttons, cards, and layout helpers
-
### Comprehensive Coverage
-
- **Typography**: Font sizes, weights, line heights, text alignment, decorations
-
- **Layout**: Display, position, flexbox, grid, spacing
-
- **Colors**: Full color palette with variants
+
### Complete Tailwind Coverage
+
- **Typography**: Font sizes, weights, text alignment with type-safe variants
+
- **Layout**: CSS Grid, Flexbox, spacing with compile-time validation
+
- **Colors**: Full palette (gray, blue, red, green, etc.) with variant checking
- **Effects**: Shadows, borders, rounded corners, transitions
-
- **Responsive**: Breakpoint-based responsive utilities
-
- **Variants**: Hover, focus, and other state variants
+
- **Components**: Pre-built buttons, cards, and layout helpers
+
- **Type Safety**: GADT-based heterogeneous lists prevent invalid combinations
-
### Using Dune
+
## Quick Start
-
Add to your `dune-project`:
-
-
```dune
-
(package
-
(name myproject)
-
(depends
-
ocaml
-
dune
-
tailwind
-
tailwind-html
-
htmlit))
-
```
-
-
## Quick Start
+
### GADT Interface (Recommended)
-
### Basic Usage
+
The new GADT-based interface provides succinct, type-safe styling with heterogeneous lists:
```ocaml
-
open Tailwind
+
open Htmlit
+
open Tailwind_html
-
(* Create a styled div *)
-
let styled_div =
-
let classes = tw [
-
Display.flex;
-
Flexbox.(to_class (justify `Center));
-
Flexbox.(to_class (align_items `Center));
-
Color.bg (Color.make `Gray ~variant:`V100 ());
-
Spacing.(to_class (p (Size.rem 2.0)));
-
] in
-
Printf.sprintf "<div class=\"%s\">Content</div>" (to_string classes)
+
(* Create a centered card with CSS Grid *)
+
let create_hero_section () =
+
div ~styles:[
+
grid;
+
grid_cols 1;
+
gap (rem 2.0);
+
padding (rem 3.0);
+
text_center;
+
] [
+
h1 ~styles:[
+
font_size `Xl3;
+
font_weight `Bold;
+
text_color (blue 600);
+
margin_bottom (rem 1.5);
+
] [txt "Welcome to Tailwind OCaml"];
+
+
p ~styles:[
+
font_size `Lg;
+
text_color (gray 600);
+
margin_bottom (rem 2.0);
+
] [txt "Type-safe CSS with compile-time guarantees"];
+
+
(* Built-in button components *)
+
btn_primary ~size:`Lg [txt "Get Started"];
+
]
```
-
### With Htmlit Integration
+
### CSS Grid Layouts
```ocaml
-
open Htmlit
-
open Tailwind
+
(* Three-column responsive grid *)
+
div ~styles:[
+
grid;
+
grid_cols 3;
+
gap (rem 1.5);
+
] [
+
card [h3 [txt "Feature 1"]; p [txt "Description"]];
+
card [h3 [txt "Feature 2"]; p [txt "Description"]];
+
card [h3 [txt "Feature 3"]; p [txt "Description"]];
+
]
+
```
-
let classes_attr tailwind_classes =
-
At.class' (Tailwind.to_string tailwind_classes)
+
### Built-in Components
-
let create_card title content =
-
El.div ~at:[classes_attr (tw [
-
Patterns.card;
-
Spacing.(to_class (p (Size.rem 1.5)));
-
Effects.shadow_md;
-
])] [
-
El.h2 ~at:[classes_attr (tw [
-
Typography.(to_class (font_size `Xl));
-
Typography.(to_class (font_weight `Bold));
-
Spacing.(to_class (mb (Size.rem 1.0)));
-
])] [El.txt title];
-
El.p [El.txt content];
-
]
+
```ocaml
+
(* Pre-styled components with size variants *)
+
btn_primary ~size:`Lg [txt "Primary Action"];
+
btn_secondary [txt "Secondary Action"];
+
btn_outline ~size:`Sm [txt "Outline Button"];
+
+
(* Layout helpers *)
+
container [
+
card [
+
h2 ~styles:[font_size `Xl; margin_bottom (rem 1.0)] [txt "Card Title"];
+
p ~styles:[text_color (gray 600)] [txt "Card content with automatic styling"];
+
];
+
]
```
## Examples
-
The `examples/` directory contains several demonstration files:
+
The `examples/` directory showcases the GADT interface across various use cases:
-
### Running Examples
+
### Available Examples
```bash
# Build all examples
dune build examples/
-
# Run comprehensive showcase (generates HTML + CSS)
-
dune exec examples/comprehensive_showcase.exe
+
# Hello World with GADT interface
+
dune exec examples/hello_tailwind_01.exe > hello.html
+
+
# Colors and Typography showcase
+
dune exec examples/colors_and_typography_02.exe > colors.html
+
+
# CSS Grid and Layout demonstrations
+
dune exec examples/layout_and_spacing_03.exe > layout.html
-
# Run basic usage example
-
dune exec examples/basic_usage.exe
+
# Responsive design patterns
+
dune exec examples/responsive_design_04.exe > responsive.html
-
# Run HTML integration example
-
dune exec examples/tailwind_html_example.exe
+
# Visual effects and styling
+
dune exec examples/effects_and_variants_05.exe > effects.html
+
+
# Component patterns and reusable elements
+
dune exec examples/patterns_and_components_06.exe > patterns.html
+
+
# Complete application showcase
+
dune exec examples/comprehensive_showcase_07.exe > showcase.html
+
+
# Button component demonstration
+
dune exec examples/button_demo.exe > buttons.html
+
+
# Generate index page linking all examples
+
dune exec examples/index_html_generator.exe > index.html
```
-
### Comprehensive Showcase
+
### Example Highlights
+
+
**CSS Grid Layout (`layout_and_spacing_03.ml`)**:
+
```ocaml
+
(* Three-column grid with gap variations *)
+
div ~styles:[
+
grid;
+
grid_cols 3;
+
gap (rem 1.0);
+
] [
+
div ~styles:[bg_color (blue 100); padding (rem 1.0)] [txt "Item 1"];
+
div ~styles:[bg_color (green 100); padding (rem 1.0)] [txt "Item 2"];
+
div ~styles:[bg_color (purple 100); padding (rem 1.0)] [txt "Item 3"];
+
]
-
The comprehensive showcase demonstrates all library features and generates:
-
- `showcase.html` - Complete HTML page with all Tailwind classes
-
- `input.css` - Tailwind v4 CSS with custom theme extensions
+
(* Asymmetric grid gaps *)
+
div ~styles:[
+
grid;
+
grid_cols 2;
+
gap_x (rem 2.0);
+
gap_y (rem 0.5);
+
] (List.init 4 (fun i ->
+
div ~styles:[bg_color (purple 200); text_center] [
+
txt (Printf.sprintf "Box %d" (i + 1))
+
]
+
))
+
```
-
```bash
-
dune exec examples/comprehensive_showcase.exe
-
# Then open showcase.html in your browser
+
**Built-in Components (`button_demo.ml`)**:
+
```ocaml
+
(* Size variants with consistent styling *)
+
div ~styles:[flex; flex_col; gap (rem 1.0)] [
+
btn_primary ~size:`Sm [txt "Small Primary"];
+
btn_primary [txt "Default Primary"];
+
btn_primary ~size:`Lg [txt "Large Primary"];
+
btn_secondary [txt "Secondary Button"];
+
btn_outline [txt "Outline Button"];
+
]
+
```
+
+
**Responsive Cards (`comprehensive_showcase_07.ml`)**:
+
```ocaml
+
section ~styles:[margin_bottom (rem 4.0)] [
+
h3 ~styles:[font_size `Xl2; text_center; margin_bottom (rem 3.0)] [
+
txt "Features"
+
];
+
+
div ~styles:[grid; grid_cols 1; gap (rem 2.0)] [
+
card [
+
h4 ~styles:[font_size `Xl; font_weight `Semibold; text_color (blue 600)] [
+
txt "🎯 Type Safety"
+
];
+
p ~styles:[text_color (gray 600)] [
+
txt "Catch styling errors at compile time with GADT-based type checking."
+
];
+
];
+
card [
+
h4 ~styles:[font_size `Xl; font_weight `Semibold; text_color (green 600)] [
+
txt "⚡ Performance"
+
];
+
p ~styles:[text_color (gray 600)] [
+
txt "Zero runtime overhead with compile-time CSS generation."
+
];
+
];
+
];
+
]
```
## Tailwind v4 Support
···
npx tailwindcss@next -i input.css -o output.css
```
-
## Module Documentation
+
## API Reference
-
### Core Modules
+
### `Tailwind_html` (GADT Interface)
-
#### `Tailwind`
-
Main module that exports all utilities and provides the `tw` function for composing classes.
+
The high-level GADT interface provides succinct, type-safe styling with heterogeneous lists:
-
#### `Color`
-
Type-safe color system with variants:
+
#### Layout Properties
```ocaml
-
Color.bg (Color.make `Blue ~variant:`V600 ())
-
Color.text Color.white
-
Color.border (Color.make `Gray ~variant:`V200 ())
+
~styles:[
+
(* Display *)
+
grid | flex | block | inline | hidden;
+
+
(* Grid System *)
+
grid_cols 3 | grid_rows 2;
+
gap (rem 1.0) | gap_x (rem 1.5) | gap_y (rem 0.5);
+
+
(* Flexbox *)
+
flex_col | flex_row;
+
justify_center | justify_between | justify_end;
+
items_center | items_start | items_end;
+
+
(* Sizing *)
+
width full | height screen;
+
min_height screen | max_width (rem 64.0);
+
]
```
-
#### `Typography`
-
Font utilities:
+
#### Typography Properties
```ocaml
-
Typography.(to_class (font_size `Xl2))
-
Typography.(to_class (font_weight `Bold))
-
Typography.(to_class (line_height `Relaxed))
+
~styles:[
+
(* Font Sizes *)
+
font_size `Xs | font_size `Sm | font_size `Base | font_size `Lg;
+
font_size `Xl | font_size `Xl2 | font_size `Xl3;
+
+
(* Font Weights *)
+
font_weight `Light | font_weight `Normal | font_weight `Medium;
+
font_weight `Semibold | font_weight `Bold;
+
+
(* Text Styling *)
+
text_center | text_left | text_right;
+
text_color (blue 600) | text_color (gray 500);
+
]
```
-
#### `Spacing`
-
Margin and padding utilities:
+
#### Color System
```ocaml
-
Spacing.(to_class (p (Size.rem 1.0))) (* padding *)
-
Spacing.(to_class (mx Size.auto)) (* margin-x auto *)
-
Spacing.(to_class (gap `All (Size.px 16.0))) (* gap *)
+
~styles:[
+
(* Background Colors *)
+
bg_color (blue 50) | bg_color (gray 100) | bg_color (red 500);
+
bg_color (Tailwind.Color.white) | bg_color (green 600);
+
+
(* Text Colors *)
+
text_color (gray 800) | text_color (blue 600) | text_color (red 500);
+
+
(* Border Colors *)
+
border_color (gray 200) | border_color (blue 300);
+
]
```
-
#### `Layout`
-
Layout utilities:
+
#### Spacing Properties
```ocaml
-
Layout.(to_class (width (Size.percent 100.0)))
-
Layout.(to_class (height Size.screen))
-
Layout.(to_class (max_width (Size.rem 64.0)))
+
~styles:[
+
(* Padding *)
+
padding (rem 1.0) | padding_x (rem 1.5) | padding_y (rem 2.0);
+
+
(* Margin *)
+
margin (rem 1.0) | margin_x auto | margin_bottom (rem 2.0);
+
margin_top (rem 1.5) | margin_left (rem 0.5);
+
]
```
-
#### `Flexbox`
-
Flexbox utilities:
+
#### Visual Effects
```ocaml
-
Display.flex
-
Flexbox.(to_class (justify `Between))
-
Flexbox.(to_class (align_items `Center))
-
Flexbox.(to_class (direction `Col))
+
~styles:[
+
(* Shadows *)
+
shadow `Sm | shadow `Md | shadow `Lg | shadow `Xl;
+
+
(* Borders *)
+
border | rounded `Sm | rounded `Md | rounded `Lg | rounded `Full;
+
+
(* Transitions *)
+
transition;
+
]
```
-
#### `Grid`
-
CSS Grid utilities:
+
#### Built-in Components
```ocaml
-
Display.grid
-
Grid.(to_class (template_cols (`Cols 3)))
-
Grid.(to_class (gap (Size.rem 1.0)))
-
```
+
(* Button Components *)
+
btn_primary ~size:`Lg [txt "Primary Button"];
+
btn_secondary ~size:`Sm [txt "Secondary Button"];
+
btn_outline [txt "Outline Button"];
+
+
(* Layout Components *)
+
container [content]; (* Max-width container with auto margins *)
+
card [content]; (* Pre-styled card with padding and shadow *)
-
#### `Effects`
-
Visual effects:
-
```ocaml
-
Effects.shadow_lg
-
Effects.rounded_md
-
Effects.border
-
Effects.transition `All
+
(* HTML Elements with Styling *)
+
h1 ~styles:[font_size `Xl3; font_weight `Bold] [txt "Heading"];
+
p ~styles:[text_color (gray 600); margin_bottom (rem 1.0)] [txt "Paragraph"];
+
div ~styles:[grid; grid_cols 2; gap (rem 1.0)] [content];
+
section ~styles:[margin_bottom (rem 2.0)] [content];
```
-
#### `Responsive`
-
Responsive utilities:
-
```ocaml
-
Responsive.(to_class (at_breakpoint `Md Display.flex))
-
Responsive.(to_class (at_breakpoint `Lg (Grid.(to_class (template_cols (`Cols 4))))))
-
```
+
### Low-Level `Tailwind` Module
-
#### `Variants`
-
State variants:
-
```ocaml
-
Variants.hover (Color.bg (Color.make `Blue ~variant:`V700 ()))
-
Variants.focus Effects.ring
-
```
+
For advanced use cases, the core `Tailwind` module provides detailed control:
-
#### `Patterns`
-
Common layout patterns:
```ocaml
-
Patterns.container ()
-
Patterns.card
-
Patterns.flex_center
-
Patterns.stack ~gap:(Size.rem 1.0) ()
-
Patterns.sticky_header
+
open Tailwind
+
+
let classes = Css.tw [
+
Display.grid;
+
Grid.(to_class (template_cols (`Cols 3)));
+
Spacing.(to_class (gap `All (Size.rem 1.0)));
+
Color.bg (Color.make `Blue ~variant:`V50 ());
+
]
+
+
let html_class = to_string classes (* "grid grid-cols-3 gap-4 bg-blue-50" *)
```
-
### HTML Components (`tailwind-html`)
+
### Getting Started
-
Pre-built components using Htmlit:
+
Add to your `dune-project`:
+
```dune
+
(package
+
(name myproject)
+
(depends
+
ocaml
+
dune
+
tailwind
+
tailwind-html
+
htmlit))
+
```
+
Then in your OCaml code:
```ocaml
+
open Htmlit
open Tailwind_html
-
(* Button component *)
-
Button.primary ~text:"Click me" ~onclick:"handleClick()"
-
-
(* Card component *)
-
Card.simple ~title:"Card Title" ~content:"Card content here"
-
-
(* Layout components *)
-
Layout.container [
-
Layout.row [
-
Layout.col ~span:6 [content];
-
Layout.col ~span:6 [content];
-
]
+
let my_page = El.html [
+
El.head [El.title [txt "My App"]];
+
El.body ~at:[classes_attr [min_height screen; bg_color (gray 50)]] [
+
container [
+
h1 ~styles:[font_size `Xl3; text_center; margin_bottom (rem 2.0)] [
+
txt "Welcome to Type-Safe CSS!"
+
];
+
btn_primary [txt "Get Started"];
+
];
+
];
]
```