@greenfinity/rescript-typed-css-modules 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -10
- package/dist/css-to-rescript.js +6 -6
- package/package.json +1 -1
- package/src/CssToRescript.bs.mjs +6 -6
- package/src/CssToRescript.res +25 -9
package/README.md
CHANGED
|
@@ -24,15 +24,13 @@ Only tested with Next.js and might not work with other frameworks out of the box
|
|
|
24
24
|
|
|
25
25
|
### Why global CSS support?
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Global CSS files (`.global.css` / `.global.scss`) also get type-safe bindings, but they are not imported, and their class names are **not hashed**. This is useful when working with third-party libraries (such as React Aria Components) that emit HTML markup with predefined class names that you need to style.
|
|
27
|
+
TL;DR: Global CSS files behave just like CSS Modules, except their class names are **not hashed** but kept as-is.
|
|
30
28
|
|
|
31
|
-
|
|
29
|
+
Support for global CSS is provided in addition to CSS Modules.
|
|
32
30
|
|
|
33
|
-
The
|
|
31
|
+
The use case is to access classes in a type safe way from third party css libraries, that emit HTML markup with predefined class names without the use of css modules (e.g. React Aria Components).
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
Even though global CSS classes aren't scoped, generating typed bindings provides the benefit of compile-time checking that class names exist. If the framework you are using supports bundling by routes (such as NextJS), the global css files will also be bundled together with JavaScript. Regarding duplicates, they should be handled the same way as CSS Modules, or ordinary JavaScript imports. (Checked with NextJS with both the Webpack and the Turbopack builder.)
|
|
36
34
|
|
|
37
35
|
## Installation
|
|
38
36
|
|
|
@@ -175,6 +173,7 @@ type t = {
|
|
|
175
173
|
"light-mode": string,
|
|
176
174
|
"primary-color": string
|
|
177
175
|
}
|
|
176
|
+
@module("./Button.module.css") external css: t = "default"
|
|
178
177
|
|
|
179
178
|
// Class names are returned as-is (no hashing)
|
|
180
179
|
let css = ...
|
|
@@ -183,10 +182,7 @@ let css = ...
|
|
|
183
182
|
Usage:
|
|
184
183
|
|
|
185
184
|
```rescript
|
|
186
|
-
//
|
|
187
|
-
%%raw(`import "./Theme.global.css"`)
|
|
188
|
-
|
|
189
|
-
// Then use type-safe class names anywhere
|
|
185
|
+
// Use type-safe class names anywhere
|
|
190
186
|
<div className={Theme_CssGlobal.css["dark-mode"]}>
|
|
191
187
|
```
|
|
192
188
|
|
package/dist/css-to-rescript.js
CHANGED
|
@@ -26620,14 +26620,14 @@ type t = {
|
|
|
26620
26620
|
}
|
|
26621
26621
|
`;
|
|
26622
26622
|
if (importType === "Module") {
|
|
26623
|
-
return prelude + (
|
|
26623
|
+
return prelude + (`
|
|
26624
|
+
@module("./` + baseName + `") external css: t = "default"
|
|
26624
26625
|
|
|
26625
26626
|
// Access class names from the fields of the css object.
|
|
26626
26627
|
// For scoped classses, the hashed class name is returned.
|
|
26627
26628
|
// For :global() classes, the class name is returned as-is: no scoping.
|
|
26628
26629
|
// Classes from @import are also available.
|
|
26629
26630
|
|
|
26630
|
-
@module("./` + baseName + `") external _imported: t = "default"
|
|
26631
26631
|
@new external proxy: ('a, 'b) => 'c = "Proxy"
|
|
26632
26632
|
%%private(
|
|
26633
26633
|
external toDict: t => dict<string> = "%identity"
|
|
@@ -26649,10 +26649,10 @@ let css = withProxy(css)
|
|
|
26649
26649
|
|
|
26650
26650
|
`);
|
|
26651
26651
|
} else {
|
|
26652
|
-
return prelude + `
|
|
26652
|
+
return prelude + (`
|
|
26653
|
+
@module("./` + baseName + `") external _imported: t = "default"
|
|
26654
|
+
|
|
26653
26655
|
// Access class names from the fields of the css object.
|
|
26654
|
-
// Import is not done, the css has to be manually imported
|
|
26655
|
-
// from the top of the component hierarchy.
|
|
26656
26656
|
// For all classes, the class name is returned as-is: no scoping.
|
|
26657
26657
|
// Classes from @import are also available.
|
|
26658
26658
|
|
|
@@ -26668,7 +26668,7 @@ type empty = {}
|
|
|
26668
26668
|
)
|
|
26669
26669
|
)
|
|
26670
26670
|
let css = withProxy({})
|
|
26671
|
-
|
|
26671
|
+
`);
|
|
26672
26672
|
}
|
|
26673
26673
|
}
|
|
26674
26674
|
function getBaseNameAndImportType(cssFilePath) {
|
package/package.json
CHANGED
package/src/CssToRescript.bs.mjs
CHANGED
|
@@ -56,14 +56,14 @@ type t = {
|
|
|
56
56
|
}
|
|
57
57
|
`;
|
|
58
58
|
if (importType === "Module") {
|
|
59
|
-
return prelude + (
|
|
59
|
+
return prelude + (`
|
|
60
|
+
@module("./` + baseName + `") external css: t = "default"
|
|
60
61
|
|
|
61
62
|
// Access class names from the fields of the css object.
|
|
62
63
|
// For scoped classses, the hashed class name is returned.
|
|
63
64
|
// For :global() classes, the class name is returned as-is: no scoping.
|
|
64
65
|
// Classes from @import are also available.
|
|
65
66
|
|
|
66
|
-
@module("./` + baseName + `") external _imported: t = "default"
|
|
67
67
|
@new external proxy: ('a, 'b) => 'c = "Proxy"
|
|
68
68
|
%%private(
|
|
69
69
|
external toDict: t => dict<string> = "%identity"
|
|
@@ -85,10 +85,10 @@ let css = withProxy(css)
|
|
|
85
85
|
|
|
86
86
|
`);
|
|
87
87
|
} else {
|
|
88
|
-
return prelude + `
|
|
88
|
+
return prelude + (`
|
|
89
|
+
@module("./` + baseName + `") external _imported: t = "default"
|
|
90
|
+
|
|
89
91
|
// Access class names from the fields of the css object.
|
|
90
|
-
// Import is not done, the css has to be manually imported
|
|
91
|
-
// from the top of the component hierarchy.
|
|
92
92
|
// For all classes, the class name is returned as-is: no scoping.
|
|
93
93
|
// Classes from @import are also available.
|
|
94
94
|
|
|
@@ -104,7 +104,7 @@ type empty = {}
|
|
|
104
104
|
)
|
|
105
105
|
)
|
|
106
106
|
let css = withProxy({})
|
|
107
|
-
|
|
107
|
+
`);
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
|
package/src/CssToRescript.res
CHANGED
|
@@ -9,7 +9,14 @@ module Meow = {
|
|
|
9
9
|
default?: bool,
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
type flags = {
|
|
12
|
+
type flags = {
|
|
13
|
+
"watch": flag,
|
|
14
|
+
"outputDir": flag,
|
|
15
|
+
"skipInitial": flag,
|
|
16
|
+
"force": flag,
|
|
17
|
+
"silent": flag,
|
|
18
|
+
"quiet": flag,
|
|
19
|
+
}
|
|
13
20
|
|
|
14
21
|
type importMeta
|
|
15
22
|
|
|
@@ -21,7 +28,14 @@ module Meow = {
|
|
|
21
28
|
|
|
22
29
|
type result = {
|
|
23
30
|
input: array<string>,
|
|
24
|
-
flags: {
|
|
31
|
+
flags: {
|
|
32
|
+
"watch": bool,
|
|
33
|
+
"outputDir": option<string>,
|
|
34
|
+
"skipInitial": bool,
|
|
35
|
+
"force": bool,
|
|
36
|
+
"silent": bool,
|
|
37
|
+
"quiet": bool,
|
|
38
|
+
},
|
|
25
39
|
showHelp: unit => unit,
|
|
26
40
|
}
|
|
27
41
|
|
|
@@ -109,14 +123,14 @@ ${recordFields->Array.join(",\n")}
|
|
|
109
123
|
// CSS Module import will get access to the object mapping returned
|
|
110
124
|
// by the import. Hashing will happen automatically.
|
|
111
125
|
prelude +
|
|
112
|
-
|
|
126
|
+
`
|
|
127
|
+
@module("./${baseName}") external css: t = "default"
|
|
113
128
|
|
|
114
129
|
// Access class names from the fields of the css object.
|
|
115
130
|
// For scoped classses, the hashed class name is returned.
|
|
116
131
|
// For :global() classes, the class name is returned as-is: no scoping.
|
|
117
132
|
// Classes from @import are also available.
|
|
118
133
|
|
|
119
|
-
@module("./${baseName}") external _imported: t = "default"
|
|
120
134
|
@new external proxy: ('a, 'b) => 'c = "Proxy"
|
|
121
135
|
%%private(
|
|
122
136
|
external toDict: t => dict<string> = "%identity"
|
|
@@ -139,11 +153,11 @@ let css = withProxy(css)
|
|
|
139
153
|
`
|
|
140
154
|
| Global =>
|
|
141
155
|
// Global css will return the css class name as-is: no scoping.
|
|
142
|
-
|
|
143
|
-
|
|
156
|
+
prelude +
|
|
157
|
+
`
|
|
158
|
+
@module("./${baseName}") external _imported: t = "default"
|
|
159
|
+
|
|
144
160
|
// Access class names from the fields of the css object.
|
|
145
|
-
// Import is not done, the css has to be manually imported
|
|
146
|
-
// from the top of the component hierarchy.
|
|
147
161
|
// For all classes, the class name is returned as-is: no scoping.
|
|
148
162
|
// Classes from @import are also available.
|
|
149
163
|
|
|
@@ -238,7 +252,9 @@ let processFile = async (cssFilePath, outputDir, ~force=false, ~silent=false, ~q
|
|
|
238
252
|
|
|
239
253
|
NodeJs.Fs.writeFileSync(outputPath, NodeJs.Buffer.fromString(bindings))
|
|
240
254
|
if !quiet {
|
|
241
|
-
Console.log(
|
|
255
|
+
Console.log(
|
|
256
|
+
`✅ Generated ${outputPath} (${classNames->Array.length->Int.toString} classes)`,
|
|
257
|
+
)
|
|
242
258
|
}
|
|
243
259
|
|
|
244
260
|
(outputPath, classNames)->Some
|