package tw

  1. Overview
  2. Docs
Type-safe Tailwind CSS v4 in OCaml

Install

dune-project
 Dependency

Authors

Maintainers

Sources

tw-1.1.0.tbz
sha256=48754ab34d0a97c37f5f2dbf50ce46747ec0ca6d483f5adbb7305fc247fb5315
sha512=f43621b49e77adc23fab3c968e5041188e428228d1930b89c307fc8916c428f1943a5d74c21467219077247021f0ba83fda9234b0dd119dfd14b7f9746332bf7

doc/src/tw/columns.ml.html

Source file columns.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
(** Columns utilities for multi-column layout

    @see <https://tailwindcss.com/docs/columns>
      Tailwind CSS Columns documentation *)

module Css = Cascade.Css

module Handler = struct
  open Style
  open Css

  type t =
    | Columns_auto
    | Columns_count of int
    | Columns_3xs
    | Columns_2xs
    | Columns_xs
    | Columns_sm
    | Columns_md
    | Columns_lg
    | Columns_xl
    | Columns_2xl
    | Columns_3xl
    | Columns_4xl
    | Columns_5xl
    | Columns_6xl
    | Columns_7xl
    | Columns_arbitrary of int
    | Columns_arbitrary_len of string * Css.length (* columns-[16rem] *)
    (* The author's text beside the value it denotes: a bracket Tailwind hands
       to the declaration unvalidated, so [columns-[0x10]] is [columns: 0x10]
       and not the [16] an OCaml number reader would fold it to. *)
    | Columns_arbitrary_raw of string * string
    | Columns_bracket_var of string

  let name = "columns"
  let priority _ = 12

  (* Helper to create a columns style with a container variable. Container theme
     variables are exported from Sizing module. *)
  let columns_with_var var default_value =
    let decl, ref_ = Var.binding var default_value in
    style [ decl; columns (Width (Var ref_)) ]

  let to_style theme = function
    | Columns_auto -> (
        let var_name = "columns-auto" in
        let ref =
          Var.theme_ref var_name
            ~default:(Auto : Css.columns_value)
            ~default_css:"auto"
        in
        match Scheme.theme_value (Some theme) var_name with
        | Some value ->
            let theme_decl =
              Css.custom_property ~layer:"theme" ("--" ^ var_name) value
            in
            style [ theme_decl; columns (Var ref) ]
        (* Without a theme override Tailwind writes the keyword, not a reference
           to a token nothing declares. *)
        | None -> style [ columns Auto ])
    | Columns_count n -> style [ columns (Count n) ]
    | Columns_3xs -> columns_with_var Sizing.container_3xs (Rem 16.0)
    | Columns_2xs -> columns_with_var Sizing.container_2xs (Rem 18.0)
    | Columns_xs -> columns_with_var Sizing.container_xs (Rem 20.0)
    | Columns_sm -> columns_with_var Sizing.container_sm (Rem 24.0)
    | Columns_md -> columns_with_var Sizing.container_md (Rem 28.0)
    | Columns_lg -> columns_with_var Sizing.container_lg (Rem 32.0)
    | Columns_xl -> columns_with_var Sizing.container_xl (Rem 36.0)
    | Columns_2xl -> columns_with_var Sizing.container_2xl (Rem 42.0)
    | Columns_3xl -> columns_with_var Sizing.container_3xl (Rem 48.0)
    | Columns_4xl -> columns_with_var Sizing.container_4xl (Rem 56.0)
    | Columns_5xl -> columns_with_var Sizing.container_5xl (Rem 64.0)
    | Columns_6xl -> columns_with_var Sizing.container_6xl (Rem 72.0)
    | Columns_7xl -> columns_with_var Sizing.container_7xl (Rem 80.0)
    | Columns_arbitrary n -> style [ columns (Count n) ]
    | Columns_arbitrary_len (_, l) -> style [ columns (Width l) ]
    | Columns_arbitrary_raw (_, v) -> (
        match Parse.opaque_declaration "columns" v with
        | Some declaration -> style [ declaration ]
        | None -> style [])
    | Columns_bracket_var s ->
        let inner = Parse.extract_var_name s in
        let ref : Css.columns_value Css.var = Var.bracket inner in
        style [ columns (Var ref) ]

  (* Every column utility shares one suborder. Tailwind orders the values of a
     single utility by a natural, digit-aware compare of the candidate itself
     (columns-9 before columns-10, columns-[100px] before columns-[100rem]),
     which is what Sort falls back to once the suborders tie. A numeric key
     built from a prefix of the suffix cannot express that order and, being
     consulted first, would override it. *)
  let suborder _ = 0

  let of_class _theme class_name =
    let parts = Parse.split_class class_name in
    match parts with
    | [ "columns"; "auto" ] -> Ok Columns_auto
    | [ "columns"; "3xs" ] -> Ok Columns_3xs
    | [ "columns"; "2xs" ] -> Ok Columns_2xs
    | [ "columns"; "xs" ] -> Ok Columns_xs
    | [ "columns"; "sm" ] -> Ok Columns_sm
    | [ "columns"; "md" ] -> Ok Columns_md
    | [ "columns"; "lg" ] -> Ok Columns_lg
    | [ "columns"; "xl" ] -> Ok Columns_xl
    | [ "columns"; "2xl" ] -> Ok Columns_2xl
    | [ "columns"; "3xl" ] -> Ok Columns_3xl
    | [ "columns"; "4xl" ] -> Ok Columns_4xl
    | [ "columns"; "5xl" ] -> Ok Columns_5xl
    | [ "columns"; "6xl" ] -> Ok Columns_6xl
    | [ "columns"; "7xl" ] -> Ok Columns_7xl
    | [ "columns"; value ] when Parse.is_bracket_var value ->
        Ok (Columns_bracket_var (Parse.bracket_inner value))
    | [ "columns"; n ] when Parse.is_bracket_value n -> (
        (* A count, a width, or the author's text as written. *)
        let inner = Parse.bracket_inner n in
        match Parse.decimal_int inner with
        | Some i -> Ok (Columns_arbitrary i)
        | None -> (
            match Parse.arbitrary_length inner with
            | Some l -> Ok (Columns_arbitrary_len (inner, l))
            | None -> (
                match Parse.arbitrary_declaration_value inner with
                | Some v -> Ok (Columns_arbitrary_raw (inner, v))
                | None -> Error (`Msg "Invalid columns arbitrary value"))))
    | [ "columns"; n ] -> (
        match Parse.decimal_int n with
        | Some i -> Ok (Columns_count i)
        | None -> Error (`Msg "Invalid columns value"))
    | _ -> Error (`Msg "Not a columns utility")

  let to_class = function
    | Columns_auto -> "columns-auto"
    | Columns_count n -> "columns-" ^ string_of_int n
    | Columns_3xs -> "columns-3xs"
    | Columns_2xs -> "columns-2xs"
    | Columns_xs -> "columns-xs"
    | Columns_sm -> "columns-sm"
    | Columns_md -> "columns-md"
    | Columns_lg -> "columns-lg"
    | Columns_xl -> "columns-xl"
    | Columns_2xl -> "columns-2xl"
    | Columns_3xl -> "columns-3xl"
    | Columns_4xl -> "columns-4xl"
    | Columns_5xl -> "columns-5xl"
    | Columns_6xl -> "columns-6xl"
    | Columns_7xl -> "columns-7xl"
    | Columns_arbitrary n -> "columns-[" ^ string_of_int n ^ "]"
    | Columns_arbitrary_len (s, _) -> "columns-[" ^ s ^ "]"
    | Columns_arbitrary_raw (s, _) -> "columns-[" ^ s ^ "]"
    | Columns_bracket_var s -> "columns-[" ^ s ^ "]"

  let examples = [ Columns_auto ]
end

open Handler
module Utility_factory = Utility.Make (Handler)

let utility = Utility_factory.v
let columns_auto = utility Columns_auto
let columns n = utility (Columns_count n)
let columns_3xs = utility Columns_3xs
let columns_2xs = utility Columns_2xs
let columns_xs = utility Columns_xs
let columns_sm = utility Columns_sm
let columns_md = utility Columns_md
let columns_lg = utility Columns_lg
let columns_xl = utility Columns_xl
let columns_2xl = utility Columns_2xl
let columns_3xl = utility Columns_3xl
let columns_4xl = utility Columns_4xl
let columns_5xl = utility Columns_5xl
let columns_6xl = utility Columns_6xl
let columns_7xl = utility Columns_7xl