rbx-css 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alrovi ApS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,270 @@
1
+ # rbx-css
2
+
3
+ CSS to Roblox StyleSheet compiler. Write standard CSS, get Luau modules or `.rbxmx` model files that create Roblox `StyleSheet` instances.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install rbx-css
9
+ # or
10
+ bun add rbx-css
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```bash
16
+ # Compile to Luau (stdout)
17
+ rbx-css compile styles.css
18
+
19
+ # Compile to file (format inferred from extension)
20
+ rbx-css compile styles.css -o StyleSheet.luau
21
+ rbx-css compile styles.css -o StyleSheet.rbxmx
22
+
23
+ # Multiple input files (merged into one StyleSheet)
24
+ rbx-css compile base.css theme.css components.css -o StyleSheet.luau
25
+
26
+ # Watch mode
27
+ rbx-css watch src/styles -o StyleSheet.luau
28
+ ```
29
+
30
+ ## CLI Reference
31
+
32
+ ### `rbx-css compile <files...>`
33
+
34
+ | Flag | Description | Default |
35
+ |------|-------------|---------|
36
+ | `-o, --output <path>` | Output file (`.luau` or `.rbxmx`) | stdout |
37
+ | `--name <name>` | StyleSheet instance name | `StyleSheet` |
38
+ | `--format <format>` | `luau` or `rbxmx` (inferred from `-o` if omitted) | `luau` |
39
+ | `--warn <level>` | `all`, `unsupported`, or `none` | `all` |
40
+ | `--strict` | Treat warnings as errors | `false` |
41
+ | `--minify` | Minify Luau output | `false` |
42
+ | `--manifest` | Emit a `.manifest.json` alongside the output | `false` |
43
+
44
+ ### `rbx-css watch <path>`
45
+
46
+ Watches a directory or file for changes and recompiles. Accepts `-o`, `--name`, `--format`, and `--warn`.
47
+
48
+ ## CSS Mapping
49
+
50
+ ### Selectors
51
+
52
+ | CSS | Roblox |
53
+ |-----|--------|
54
+ | `div`, `button`, `span`, ... | `Frame`, `TextButton`, `TextLabel`, ... |
55
+ | `Frame`, `TextLabel`, ... | Direct Roblox class names pass through unchanged |
56
+ | `.card` | `.card` (class selector) |
57
+ | `#sidebar` | `#sidebar` (name selector) |
58
+ | `button.primary` | `TextButton.primary` |
59
+ | `.card > span` | `.card > TextLabel` (child combinator) |
60
+ | `.card span` | `.card TextLabel` (descendant combinator) |
61
+ | `:hover` | `:Hover` |
62
+ | `:active` | `:Press` |
63
+ | `:focus`, `:disabled` | `:NonDefault` |
64
+
65
+ Special characters in class/ID names are automatically escaped, so Tailwind-style selectors like `.text-\[22px\]` or `.gap-0\.5` work correctly.
66
+
67
+ ### Element Mapping
68
+
69
+ | HTML | Roblox |
70
+ |------|--------|
71
+ | `div`, `nav`, `header`, `footer`, `main`, `section`, `article`, `aside`, `form`, `ul`, `ol`, `li`, `table`, `dialog`, `details`, `select` | `Frame` |
72
+ | `span`, `p`, `h1`–`h6`, `label`, `td`, `th` | `TextLabel` |
73
+ | `button`, `a`, `summary`, `option` | `TextButton` |
74
+ | `input`, `textarea` | `TextBox` |
75
+ | `img` | `ImageLabel` |
76
+ | `canvas` | `ViewportFrame` |
77
+ | `video` | `VideoFrame` |
78
+ | `scroll` | `ScrollingFrame` |
79
+
80
+ ### Design Tokens
81
+
82
+ CSS custom properties on `:root` become StyleSheet attributes:
83
+
84
+ ```css
85
+ :root {
86
+ --primary: #335fff; /* Color3 */
87
+ --radius: 8px; /* UDim */
88
+ --gap: 12px; /* UDim */
89
+ }
90
+ ```
91
+
92
+ Reference them with `var()`:
93
+
94
+ ```css
95
+ .card {
96
+ background-color: var(--primary);
97
+ border-radius: var(--radius);
98
+ }
99
+ ```
100
+
101
+ Token types are automatically inferred: colors → `Color3`, lengths → `UDim`, numbers → `number`, strings → `string`.
102
+
103
+ ### Pseudo-Instances
104
+
105
+ CSS properties that map to Roblox child instances are emitted as separate `::Component` rules:
106
+
107
+ | CSS | Roblox Pseudo-Instance |
108
+ |-----|------------------------|
109
+ | `border-radius` | `UICorner` |
110
+ | `border`, `outline` | `UIStroke` |
111
+ | `padding` | `UIPadding` |
112
+ | `display: flex` + flex props | `UIListLayout` |
113
+ | `display: grid` + grid props | `UIGridLayout` |
114
+ | `flex-grow`, `flex-shrink`, `align-self` | `UIFlexItem` |
115
+ | `linear-gradient()` | `UIGradient` |
116
+ | `transform: scale()` | `UIScale` |
117
+ | `aspect-ratio` | `UIAspectRatioConstraint` |
118
+ | `min-width`, `max-height`, etc. | `UISizeConstraint` |
119
+
120
+ ### CSS Nesting
121
+
122
+ Standard CSS nesting is supported:
123
+
124
+ ```css
125
+ .card {
126
+ background-color: white;
127
+
128
+ &:hover {
129
+ background-color: #f0f0f0;
130
+ }
131
+
132
+ > span {
133
+ color: gray;
134
+ }
135
+ }
136
+ ```
137
+
138
+ ### Themes
139
+
140
+ Define themes with `[data-theme]` or `@media (prefers-color-scheme)`:
141
+
142
+ ```css
143
+ :root { --bg: white; --text: black; }
144
+
145
+ [data-theme="dark"] {
146
+ --bg: #1a1a2e;
147
+ --text: #e1e1e1;
148
+ }
149
+
150
+ /* or */
151
+ @media (prefers-color-scheme: dark) {
152
+ :root {
153
+ --bg: #1a1a2e;
154
+ --text: #e1e1e1;
155
+ }
156
+ }
157
+ ```
158
+
159
+ The output includes a `setTheme(name)` helper function and theme StyleSheets connected via `StyleDerive`.
160
+
161
+ ### Units
162
+
163
+ | CSS | Roblox |
164
+ |-----|--------|
165
+ | `px` | `UDim(0, n)` |
166
+ | `rem` | `UDim(0, n * 16)` |
167
+ | `em` | `UDim(0, n * 16)` (approximated as rem) |
168
+ | `%` | `UDim(n, 0)` |
169
+ | `vw`, `vh` | `UDim(n/100, 0)` |
170
+ | `auto` | `Enum.AutomaticSize` |
171
+
172
+ ### Colors
173
+
174
+ All standard CSS color formats are supported — `lightningcss` normalizes most formats (hex, `hsl()`, `hwb()`, named colors, etc.) to `rgb()` internally. Additionally supported natively:
175
+
176
+ - `rgb()` / `rgba()`
177
+ - `oklch()`, `oklab()`
178
+ - `lab()`, `lch()`
179
+
180
+ Alpha channels map to Roblox transparency values.
181
+
182
+ ### Fonts
183
+
184
+ | CSS `font-family` | Roblox Font |
185
+ |--------------------|-------------|
186
+ | `gotham`, `gothamssm` | GothamSSm |
187
+ | `builder sans` | BuilderSans |
188
+ | `source sans pro` | SourceSansPro |
189
+ | `roboto` | Roboto |
190
+ | `montserrat` | Montserrat |
191
+ | `monospace` | RobotoMono |
192
+ | `sans-serif` | GothamSSm |
193
+ | `serif` | Merriweather |
194
+
195
+ Unknown font families are assumed to exist at `rbxasset://fonts/families/{name}.json`. Font weight (100–900) and font style (`italic`/`normal`) are combined into a single Roblox `Font` value on the `FontFace` property.
196
+
197
+ ## Supported Properties
198
+
199
+ ### Layout & Sizing
200
+
201
+ `display` (flex, grid, none), `width`, `height`, `min-width`, `max-width`, `min-height`, `max-height`, `left`, `top`, `aspect-ratio`, `overflow` (hidden, scroll), `visibility`, `z-index`
202
+
203
+ ### Flexbox
204
+
205
+ `flex-direction`, `justify-content`, `align-items`, `flex-wrap`, `gap`, `flex-grow`, `flex-shrink`, `flex-basis`, `align-self`, `order`
206
+
207
+ ### Grid
208
+
209
+ `grid-template-columns`, `grid-template-rows` (px/rem track sizes)
210
+
211
+ ### Box Model
212
+
213
+ `padding` (shorthand and per-side), `padding-inline`, `padding-block`, `padding-inline-start/end`, `padding-block-start/end`, `border` (shorthand and per-side), `border-color`, `border-width`, `border-style`, `border-radius`, `outline`
214
+
215
+ ### Typography
216
+
217
+ `font-size`, `font-family`, `font-weight`, `font-style`, `text-align`, `vertical-align`, `line-height`, `word-wrap` / `overflow-wrap`, `text-overflow`, `color`
218
+
219
+ ### Visual
220
+
221
+ `background-color`, `background` (solid color or gradient), `background-image` (url or linear-gradient), `opacity`, `object-fit`, `transform` (scale, rotate), `transform-origin` (maps to `AnchorPoint`)
222
+
223
+ Unsupported properties emit a warning (suppressible with `--warn none`). Common web-only properties (transitions, animations, shadows, etc.) are silently ignored.
224
+
225
+ ## Base Element Rules
226
+
227
+ The compiler auto-prepends low-specificity base rules to match common Roblox defaults:
228
+
229
+ - `TextLabel`, `TextButton` — `AutomaticSize = XY`, `BackgroundTransparency = 1`
230
+ - `TextBox` — `AutomaticSize = XY`
231
+ - `Frame`, `ScrollingFrame` — `BackgroundTransparency = 1`
232
+
233
+ These can be overridden by your CSS rules.
234
+
235
+ ## Manifest
236
+
237
+ When using `--manifest` with `-o`, a `.manifest.json` file is generated alongside the output containing metadata about the compiled stylesheet — for example, which classes use `overflow: scroll` (useful for tools like rbx-tsx that need to upgrade `Frame` to `ScrollingFrame`).
238
+
239
+ ## Output Formats
240
+
241
+ ### Luau (default)
242
+
243
+ Generates a `.luau` module returning a `createStyleSheet()` factory function. This is the recommended format.
244
+
245
+ ### RBXMX
246
+
247
+ Generates a `.rbxmx` model file. Note: RBXMX output is currently **experimental** — StyleRule properties are emitted as XML comments rather than fully encoded RBXMX properties. The Luau format is recommended for production use.
248
+
249
+ ## Programmatic API
250
+
251
+ In addition to the CLI, you can use rbx-css as a library:
252
+
253
+ ```ts
254
+ import { compile, generateLuau, generateRBXMX } from "rbx-css";
255
+
256
+ const result = compile(
257
+ [{ filename: "styles.css", content: "div { background-color: red; }" }],
258
+ { name: "MyStyleSheet", warnLevel: "all", strict: false }
259
+ );
260
+
261
+ // result.ir — intermediate representation (StyleSheetIR)
262
+ // result.warnings — WarningCollector with any diagnostics
263
+
264
+ const luau = generateLuau(result.ir, { minify: false });
265
+ const rbxmx = generateRBXMX(result.ir);
266
+ ```
267
+
268
+ ## License
269
+
270
+ MIT