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 +21 -0
- package/README.md +270 -0
- package/dist/index.js +5046 -0
- package/dist/lib.js +2812 -0
- package/package.json +30 -0
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
|