@umoa/saascfm-css 0.0.0-stage → 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 +12 -0
- package/README.md +133 -2
- package/client.d.ts +1 -0
- package/dist/index.cjs +565 -0
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +534 -0
- package/package.json +57 -3
- package/templates/js/minimal/app.colors.js +25 -0
- package/templates/js/sectioned/app.colors.js +14 -0
- package/templates/js/sectioned/border.colors.js +7 -0
- package/templates/js/sectioned/navigation.colors.js +9 -0
- package/templates/js/sectioned/primitives.colors.js +32 -0
- package/templates/js/sectioned/status.colors.js +21 -0
- package/templates/js/sectioned/surface.colors.js +17 -0
- package/templates/js/single/app.colors.js +89 -0
- package/templates/ts/minimal/app.colors.ts +25 -0
- package/templates/ts/sectioned/app.colors.ts +14 -0
- package/templates/ts/sectioned/border.colors.ts +7 -0
- package/templates/ts/sectioned/navigation.colors.ts +9 -0
- package/templates/ts/sectioned/primitives.colors.ts +32 -0
- package/templates/ts/sectioned/status.colors.ts +21 -0
- package/templates/ts/sectioned/surface.colors.ts +17 -0
- package/templates/ts/single/app.colors.ts +89 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
default: () => cssModule
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
37
|
+
var import_node_fs = __toESM(require("fs"), 1);
|
|
38
|
+
|
|
39
|
+
// src/layout/css-spacing.ts
|
|
40
|
+
var SPACING_RULES = {
|
|
41
|
+
// sizing
|
|
42
|
+
w: { props: ["width"] },
|
|
43
|
+
h: { props: ["height"] },
|
|
44
|
+
mw: { props: ["max-width"] },
|
|
45
|
+
mh: { props: ["max-height"] },
|
|
46
|
+
minw: { props: ["min-width"] },
|
|
47
|
+
minh: { props: ["min-height"] },
|
|
48
|
+
// margin
|
|
49
|
+
mt: { props: ["margin-top"] },
|
|
50
|
+
mr: { props: ["margin-right"] },
|
|
51
|
+
mb: { props: ["margin-bottom"] },
|
|
52
|
+
ml: { props: ["margin-left"] },
|
|
53
|
+
mtb: { props: ["margin-top", "margin-bottom"] },
|
|
54
|
+
mrl: { props: ["margin-right", "margin-left"] },
|
|
55
|
+
// padding
|
|
56
|
+
p: { props: ["padding"] },
|
|
57
|
+
pt: { props: ["padding-top"] },
|
|
58
|
+
pr: { props: ["padding-right"] },
|
|
59
|
+
pb: { props: ["padding-bottom"] },
|
|
60
|
+
pl: { props: ["padding-left"] },
|
|
61
|
+
ptb: { props: ["padding-top", "padding-bottom"] },
|
|
62
|
+
prl: { props: ["padding-right", "padding-left"] },
|
|
63
|
+
// gap
|
|
64
|
+
g: { props: ["gap"], nonNegative: true },
|
|
65
|
+
gc: { props: ["column-gap"], nonNegative: true },
|
|
66
|
+
gr: { props: ["row-gap"], nonNegative: true },
|
|
67
|
+
// misc
|
|
68
|
+
bdrd: { props: ["border-radius"] },
|
|
69
|
+
bdw: { props: ["border-width"], companion: { "border-style": "solid" } },
|
|
70
|
+
zdex: { props: ["z-index"], unitless: true }
|
|
71
|
+
};
|
|
72
|
+
var SPACING_PERCENT_ENABLED = /* @__PURE__ */ new Set([
|
|
73
|
+
"w",
|
|
74
|
+
"h",
|
|
75
|
+
"mw",
|
|
76
|
+
"mh",
|
|
77
|
+
"minw",
|
|
78
|
+
"minh",
|
|
79
|
+
"mt",
|
|
80
|
+
"mr",
|
|
81
|
+
"mb",
|
|
82
|
+
"ml",
|
|
83
|
+
"mtb",
|
|
84
|
+
"mrl",
|
|
85
|
+
"p",
|
|
86
|
+
"pt",
|
|
87
|
+
"pr",
|
|
88
|
+
"pb",
|
|
89
|
+
"pl",
|
|
90
|
+
"ptb",
|
|
91
|
+
"prl"
|
|
92
|
+
]);
|
|
93
|
+
var SPACING_VIEWPORT_ENABLED = /* @__PURE__ */ new Set(["w", "h"]);
|
|
94
|
+
var SPACING_ORDER = [
|
|
95
|
+
"w",
|
|
96
|
+
"h",
|
|
97
|
+
"mw",
|
|
98
|
+
"mh",
|
|
99
|
+
"minw",
|
|
100
|
+
"minh",
|
|
101
|
+
"p",
|
|
102
|
+
"ptb",
|
|
103
|
+
"prl",
|
|
104
|
+
"pt",
|
|
105
|
+
"pr",
|
|
106
|
+
"pb",
|
|
107
|
+
"pl",
|
|
108
|
+
"mtb",
|
|
109
|
+
"mrl",
|
|
110
|
+
"mt",
|
|
111
|
+
"mr",
|
|
112
|
+
"mb",
|
|
113
|
+
"ml",
|
|
114
|
+
"g",
|
|
115
|
+
"gc",
|
|
116
|
+
"gr",
|
|
117
|
+
"bdrd",
|
|
118
|
+
"bdw",
|
|
119
|
+
"zdex"
|
|
120
|
+
];
|
|
121
|
+
var SPACING_ALTERNATION = Object.keys(SPACING_RULES).sort((a, b) => b.length - a.length).join("|");
|
|
122
|
+
|
|
123
|
+
// src/layout/css-spacing-static.ts
|
|
124
|
+
var SPACING_STATIC_RULES = {
|
|
125
|
+
bn: { border: "none" },
|
|
126
|
+
auto: { margin: "0 auto" },
|
|
127
|
+
hl: { "border-bottom": "1px solid var(--border-default, currentColor)", width: "100%" },
|
|
128
|
+
"hl-muted": { "border-bottom": "1px solid var(--border-muted, var(--border-default, currentColor))", width: "100%" },
|
|
129
|
+
vl: { "border-left": "2px solid var(--border-default, currentColor)", height: "20px" },
|
|
130
|
+
"mcon-480": { "max-width": "480px", margin: "0 auto" },
|
|
131
|
+
"mcon-640": { "max-width": "640px", margin: "0 auto" },
|
|
132
|
+
"mcon-768": { "max-width": "768px", margin: "0 auto" },
|
|
133
|
+
"mcon-1080": { "max-width": "1080px", margin: "0 auto" },
|
|
134
|
+
"mcon-1280": { "max-width": "1280px", margin: "0 auto" },
|
|
135
|
+
"mcon-1440": { "max-width": "1440px", margin: "0 auto" }
|
|
136
|
+
};
|
|
137
|
+
var SPACING_STATIC_ALTERNATION = Object.keys(SPACING_STATIC_RULES).sort((a, b) => b.length - a.length).join("|");
|
|
138
|
+
|
|
139
|
+
// src/layout/css-layout.ts
|
|
140
|
+
var LAYOUT_RULES = {
|
|
141
|
+
// flex container
|
|
142
|
+
flex: { display: "flex" },
|
|
143
|
+
"flex-fdr": { "flex-direction": "row" },
|
|
144
|
+
"flex-fdrr": { "flex-direction": "row-reverse" },
|
|
145
|
+
"flex-fdc": { "flex-direction": "column" },
|
|
146
|
+
"flex-fdcr": { "flex-direction": "column-reverse" },
|
|
147
|
+
"flex-wrap": { "flex-wrap": "wrap" },
|
|
148
|
+
"flex-nowrap": { "flex-wrap": "nowrap" },
|
|
149
|
+
// flex justify-content
|
|
150
|
+
"flex-jcfs": { "justify-content": "flex-start" },
|
|
151
|
+
"flex-jcfe": { "justify-content": "flex-end" },
|
|
152
|
+
"flex-jcc": { "justify-content": "center" },
|
|
153
|
+
"flex-jcsb": { "justify-content": "space-between" },
|
|
154
|
+
"flex-jcsa": { "justify-content": "space-around" },
|
|
155
|
+
"flex-jcse": { "justify-content": "space-evenly" },
|
|
156
|
+
// flex align-items
|
|
157
|
+
"flex-aifs": { "align-items": "flex-start" },
|
|
158
|
+
"flex-aife": { "align-items": "flex-end" },
|
|
159
|
+
"flex-aic": { "align-items": "center" },
|
|
160
|
+
"flex-aist": { "align-items": "stretch" },
|
|
161
|
+
"flex-aib": { "align-items": "baseline" },
|
|
162
|
+
// flex align-content
|
|
163
|
+
"flex-acfs": { "align-content": "flex-start" },
|
|
164
|
+
"flex-acfe": { "align-content": "flex-end" },
|
|
165
|
+
"flex-acc": { "align-content": "center" },
|
|
166
|
+
"flex-acst": { "align-content": "stretch" },
|
|
167
|
+
"flex-acsb": { "align-content": "space-between" },
|
|
168
|
+
"flex-acsa": { "align-content": "space-around" },
|
|
169
|
+
// flex align-self
|
|
170
|
+
"flex-assr": { "align-self": "stretch" },
|
|
171
|
+
"flex-asc": { "align-self": "center" },
|
|
172
|
+
"flex-ass": { "align-self": "start" },
|
|
173
|
+
"flex-ase": { "align-self": "end" },
|
|
174
|
+
// grid justify-items
|
|
175
|
+
"grid-jist": { "justify-items": "start" },
|
|
176
|
+
"grid-jie": { "justify-items": "end" },
|
|
177
|
+
"grid-jic": { "justify-items": "center" },
|
|
178
|
+
"grid-jistr": { "justify-items": "stretch" },
|
|
179
|
+
// grid align-items
|
|
180
|
+
"grid-aist": { "align-items": "start" },
|
|
181
|
+
"grid-aie": { "align-items": "end" },
|
|
182
|
+
"grid-aic": { "align-items": "center" },
|
|
183
|
+
"grid-aistr": { "align-items": "stretch" },
|
|
184
|
+
// text-align (found in the legacy file, was missing from the module)
|
|
185
|
+
"align-l": { "text-align": "left" },
|
|
186
|
+
"align-c": { "text-align": "center" },
|
|
187
|
+
"align-r": { "text-align": "right" },
|
|
188
|
+
// float
|
|
189
|
+
"float-l": { float: "left" },
|
|
190
|
+
"float-r": { float: "right" },
|
|
191
|
+
// float-c in the legacy file was actually `position: fixed; top: 50%; left: 50%`,
|
|
192
|
+
// not a real float — kept as its original (odd) behavior rather than
|
|
193
|
+
// silently "fixing" it into something it never was.
|
|
194
|
+
"float-c": { position: "fixed", top: "50%", left: "50%" }
|
|
195
|
+
};
|
|
196
|
+
var LAYOUT_ALTERNATION = Object.keys(LAYOUT_RULES).sort((a, b) => b.length - a.length).join("|");
|
|
197
|
+
|
|
198
|
+
// src/styling/css-typography.ts
|
|
199
|
+
var TYPOGRAPHY_RULES = {
|
|
200
|
+
// font-weight
|
|
201
|
+
nb: { "font-weight": "normal" },
|
|
202
|
+
b: { "font-weight": "bold" },
|
|
203
|
+
bx: { "font-weight": "bolder" },
|
|
204
|
+
"b-100": { "font-weight": "100" },
|
|
205
|
+
"b-200": { "font-weight": "200" },
|
|
206
|
+
"b-300": { "font-weight": "300" },
|
|
207
|
+
"b-400": { "font-weight": "400" },
|
|
208
|
+
"b-500": { "font-weight": "500" },
|
|
209
|
+
"b-600": { "font-weight": "600" },
|
|
210
|
+
"b-700": { "font-weight": "700" },
|
|
211
|
+
"b-800": { "font-weight": "800" },
|
|
212
|
+
"b-900": { "font-weight": "900" },
|
|
213
|
+
"b-lighter": { "font-weight": "100" },
|
|
214
|
+
"b-light": { "font-weight": "300" },
|
|
215
|
+
lighter: { "font-weight": "100" },
|
|
216
|
+
light: { "font-weight": "300" },
|
|
217
|
+
// text-transform
|
|
218
|
+
uppercase: { "text-transform": "uppercase" },
|
|
219
|
+
"to-uppercase": { "text-transform": "uppercase" },
|
|
220
|
+
lowercase: { "text-transform": "lowercase" },
|
|
221
|
+
"to-lowercase": { "text-transform": "lowercase" },
|
|
222
|
+
capitalize: { "text-transform": "capitalize" },
|
|
223
|
+
"text-none": { "text-transform": "none" },
|
|
224
|
+
// misc
|
|
225
|
+
i: { "font-style": "italic" },
|
|
226
|
+
underline: { "text-decoration": "underline" },
|
|
227
|
+
// word-wrap / hyphenation
|
|
228
|
+
ow: { "overflow-wrap": "break-word", "word-wrap": "break-word", hyphens: "auto" },
|
|
229
|
+
ww: { "overflow-wrap": "break-word", "word-wrap": "break-word", hyphens: "auto" }
|
|
230
|
+
};
|
|
231
|
+
var TYPOGRAPHY_ALTERNATION = Object.keys(TYPOGRAPHY_RULES).sort((a, b) => b.length - a.length).join("|");
|
|
232
|
+
var FONT_SIZE_PATTERN = "(?:fs|ls)-n?(?:\\d+)?(?:[dp]\\d+)?em";
|
|
233
|
+
function parseFontSize(cls) {
|
|
234
|
+
const match = cls.match(/^(fs|ls)-(n)?(\d+)?(?:[dp](\d+))?em$/);
|
|
235
|
+
if (!match) return null;
|
|
236
|
+
const [, kind, neg, intPart, decPart] = match;
|
|
237
|
+
if (!intPart && !decPart) return null;
|
|
238
|
+
if (neg && kind === "fs") return null;
|
|
239
|
+
const whole = intPart ?? "0";
|
|
240
|
+
const num = decPart ? `${whole}.${decPart}` : whole;
|
|
241
|
+
return {
|
|
242
|
+
prop: kind === "fs" ? "font-size" : "letter-spacing",
|
|
243
|
+
value: `${neg ? "-" : ""}${num}em`
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// src/styling/css-cursor.ts
|
|
248
|
+
var CURSOR_RULES = {
|
|
249
|
+
"cursor-alias": { cursor: "alias" },
|
|
250
|
+
"cursor-all-scroll": { cursor: "all-scroll" },
|
|
251
|
+
"cursor-auto": { cursor: "auto" },
|
|
252
|
+
"cursor-cell": { cursor: "cell" },
|
|
253
|
+
"cursor-context-menu": { cursor: "context-menu" },
|
|
254
|
+
"cursor-col-resize": { cursor: "col-resize" },
|
|
255
|
+
"cursor-copy": { cursor: "copy" },
|
|
256
|
+
"cursor-crosshair": { cursor: "crosshair" },
|
|
257
|
+
"cursor-default": { cursor: "default" },
|
|
258
|
+
"cursor-e-resize": { cursor: "e-resize" },
|
|
259
|
+
"cursor-ew-resize": { cursor: "ew-resize" },
|
|
260
|
+
"cursor-grab": { cursor: "grab" },
|
|
261
|
+
"cursor-grabbing": { cursor: "grabbing" },
|
|
262
|
+
"cursor-help": { cursor: "help" },
|
|
263
|
+
"cursor-move": { cursor: "move" },
|
|
264
|
+
"cursor-n-resize": { cursor: "n-resize" },
|
|
265
|
+
"cursor-ne-resize": { cursor: "ne-resize" },
|
|
266
|
+
"cursor-nesw-resize": { cursor: "nesw-resize" },
|
|
267
|
+
"cursor-ns-resize": { cursor: "ns-resize" },
|
|
268
|
+
"cursor-nw-resize": { cursor: "nw-resize" },
|
|
269
|
+
"cursor-nwse-resize": { cursor: "nwse-resize" },
|
|
270
|
+
"cursor-no-drop": { cursor: "no-drop" },
|
|
271
|
+
"cursor-none": { cursor: "none" },
|
|
272
|
+
"cursor-not-allowed": { cursor: "not-allowed" },
|
|
273
|
+
"cursor-pointer": { cursor: "pointer" },
|
|
274
|
+
"cursor-progress": { cursor: "progress" },
|
|
275
|
+
"cursor-row-resize": { cursor: "row-resize" },
|
|
276
|
+
"cursor-s-resize": { cursor: "s-resize" },
|
|
277
|
+
"cursor-se-resize": { cursor: "se-resize" },
|
|
278
|
+
"cursor-sw-resize": { cursor: "sw-resize" },
|
|
279
|
+
"cursor-text": { cursor: "text" },
|
|
280
|
+
"cursor-w-resize": { cursor: "w-resize" },
|
|
281
|
+
"cursor-wait": { cursor: "wait" },
|
|
282
|
+
"cursor-zoom-in": { cursor: "zoom-in" },
|
|
283
|
+
"cursor-zoom-out": { cursor: "zoom-out" }
|
|
284
|
+
};
|
|
285
|
+
var CURSOR_ALTERNATION = Object.keys(CURSOR_RULES).sort((a, b) => b.length - a.length).join("|");
|
|
286
|
+
|
|
287
|
+
// src/styling/css-border.ts
|
|
288
|
+
var BORDER_STYLE_RULES = {
|
|
289
|
+
"bds-solid": { "border-style": "solid" },
|
|
290
|
+
"bds-dashed": { "border-style": "dashed" },
|
|
291
|
+
"bds-dotted": { "border-style": "dotted" },
|
|
292
|
+
"bds-double": { "border-style": "double" },
|
|
293
|
+
"bds-none": { "border-style": "none" }
|
|
294
|
+
};
|
|
295
|
+
var BORDER_STYLE_ALTERNATION = Object.keys(BORDER_STYLE_RULES).sort((a, b) => b.length - a.length).join("|");
|
|
296
|
+
|
|
297
|
+
// src/styling/css-color.ts
|
|
298
|
+
var PROP_BY_PREFIX = {
|
|
299
|
+
text: "color",
|
|
300
|
+
bg: "background-color",
|
|
301
|
+
border: "border-color"
|
|
302
|
+
};
|
|
303
|
+
var LOOKS_LIKE_KEY = /^[a-z][a-z0-9]*(-[a-z0-9]+)+$/i;
|
|
304
|
+
function resolveTokens(tokens, palette) {
|
|
305
|
+
const resolved = {};
|
|
306
|
+
for (const [name, value] of Object.entries(tokens)) {
|
|
307
|
+
if (typeof value !== "string" || !value) {
|
|
308
|
+
console.warn(`[saascfm-css] token "${name}" has no value, skipped`);
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
const fromPalette = palette[value];
|
|
312
|
+
if (!fromPalette && LOOKS_LIKE_KEY.test(value)) {
|
|
313
|
+
console.warn(`[saascfm-css] token "${name}" references unknown primitive "${value}", skipped`);
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
resolved[name] = fromPalette ?? value;
|
|
317
|
+
}
|
|
318
|
+
return resolved;
|
|
319
|
+
}
|
|
320
|
+
function generateRootVars(resolved) {
|
|
321
|
+
const lines = Object.entries(resolved).sort(([a], [b]) => a.localeCompare(b)).map(([name, value]) => ` --${name}: ${value};`);
|
|
322
|
+
return `:root {
|
|
323
|
+
${lines.join("\n")}
|
|
324
|
+
}
|
|
325
|
+
`;
|
|
326
|
+
}
|
|
327
|
+
function buildColorUtilityRules(resolved) {
|
|
328
|
+
const rules = {};
|
|
329
|
+
for (const name of Object.keys(resolved)) {
|
|
330
|
+
const prop = PROP_BY_PREFIX[name.split("-")[0]];
|
|
331
|
+
if (!prop) continue;
|
|
332
|
+
rules[name] = { [prop]: `var(--${name})` };
|
|
333
|
+
}
|
|
334
|
+
return rules;
|
|
335
|
+
}
|
|
336
|
+
function buildPrimitiveRules(primitives) {
|
|
337
|
+
const rules = {};
|
|
338
|
+
for (const [name, value] of Object.entries(primitives)) {
|
|
339
|
+
rules[name] = { color: value };
|
|
340
|
+
if (/^(rgba|hsla)/i.test(value)) continue;
|
|
341
|
+
rules[`bg-${name}`] = { "background-color": value };
|
|
342
|
+
rules[`border-${name}`] = { "border-color": value };
|
|
343
|
+
}
|
|
344
|
+
return rules;
|
|
345
|
+
}
|
|
346
|
+
function colorAlternation(rules) {
|
|
347
|
+
return Object.keys(rules).sort((a, b) => b.length - a.length).join("|");
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// src/index.ts
|
|
351
|
+
var PKG = "saascfm-css";
|
|
352
|
+
var VIRTUAL_ID = "virtual:css-module.css";
|
|
353
|
+
var RESOLVED_VIRTUAL_ID = "\0" + VIRTUAL_ID;
|
|
354
|
+
function cssModule(options = {}) {
|
|
355
|
+
const srcDir = options.srcDir || "src";
|
|
356
|
+
const extensions = options.extensions || [".vue", ".js", ".jsx", ".ts", ".tsx", ".html"];
|
|
357
|
+
const exclude = options.exclude || [".colors.", ".tokens.", "primitives."];
|
|
358
|
+
const useSpacing = options.spacing !== false;
|
|
359
|
+
const useLayout = options.layout !== false;
|
|
360
|
+
const useTypography = options.typography !== false;
|
|
361
|
+
const useCursor = options.cursor !== false;
|
|
362
|
+
const useBorder = options.border !== false;
|
|
363
|
+
let COLOR_ROOT_VARS = "";
|
|
364
|
+
let COLOR_RULES = {};
|
|
365
|
+
let PRIMITIVE_COLOR_RULES = {};
|
|
366
|
+
let COLOR_ALTERNATION = "";
|
|
367
|
+
const colorsModule = options.colorsModule ?? {};
|
|
368
|
+
const tokens = colorsModule["TOKENS"];
|
|
369
|
+
const primitives = colorsModule["PRIMITIVES"];
|
|
370
|
+
const useColor = !!(tokens || primitives);
|
|
371
|
+
if (useColor) {
|
|
372
|
+
if (tokens) {
|
|
373
|
+
const resolved = resolveTokens(tokens, primitives ?? {});
|
|
374
|
+
COLOR_ROOT_VARS = generateRootVars(resolved);
|
|
375
|
+
COLOR_RULES = buildColorUtilityRules(resolved);
|
|
376
|
+
}
|
|
377
|
+
if (primitives && options.primitiveClasses !== false) {
|
|
378
|
+
PRIMITIVE_COLOR_RULES = buildPrimitiveRules(primitives);
|
|
379
|
+
}
|
|
380
|
+
COLOR_ALTERNATION = colorAlternation({ ...COLOR_RULES, ...PRIMITIVE_COLOR_RULES });
|
|
381
|
+
}
|
|
382
|
+
const alternatives = [];
|
|
383
|
+
if (useSpacing) {
|
|
384
|
+
alternatives.push(`(?:${SPACING_ALTERNATION})-n?\\d+(?:d\\d+)?(?:p|vw|vh)?`);
|
|
385
|
+
alternatives.push(`(?:${SPACING_STATIC_ALTERNATION})`);
|
|
386
|
+
}
|
|
387
|
+
if (useLayout) alternatives.push(`(?:${LAYOUT_ALTERNATION})`);
|
|
388
|
+
if (useTypography) {
|
|
389
|
+
alternatives.push(`(?:${TYPOGRAPHY_ALTERNATION})`);
|
|
390
|
+
alternatives.push(FONT_SIZE_PATTERN);
|
|
391
|
+
}
|
|
392
|
+
if (useCursor) alternatives.push(`(?:${CURSOR_ALTERNATION})`);
|
|
393
|
+
if (useBorder) alternatives.push(`(?:${BORDER_STYLE_ALTERNATION})`);
|
|
394
|
+
if (useColor && COLOR_ALTERNATION) alternatives.push(`(?:${COLOR_ALTERNATION})`);
|
|
395
|
+
const CLASS_RE = new RegExp(
|
|
396
|
+
`(?:^|["'\`\\s(])(${alternatives.join("|")})(!)?(?=["'\`\\s)]|$)`,
|
|
397
|
+
"g"
|
|
398
|
+
);
|
|
399
|
+
function parseClass(cls) {
|
|
400
|
+
if (useSpacing && SPACING_STATIC_RULES[cls]) {
|
|
401
|
+
return { kind: "static", decls: SPACING_STATIC_RULES[cls] };
|
|
402
|
+
}
|
|
403
|
+
if (useLayout && LAYOUT_RULES[cls]) {
|
|
404
|
+
return { kind: "static", decls: LAYOUT_RULES[cls] };
|
|
405
|
+
}
|
|
406
|
+
if (useTypography && TYPOGRAPHY_RULES[cls]) {
|
|
407
|
+
return { kind: "static", decls: TYPOGRAPHY_RULES[cls] };
|
|
408
|
+
}
|
|
409
|
+
if (useCursor && CURSOR_RULES[cls]) {
|
|
410
|
+
return { kind: "static", decls: CURSOR_RULES[cls] };
|
|
411
|
+
}
|
|
412
|
+
if (useBorder && BORDER_STYLE_RULES[cls]) {
|
|
413
|
+
return { kind: "static", decls: BORDER_STYLE_RULES[cls] };
|
|
414
|
+
}
|
|
415
|
+
if (useColor && COLOR_RULES[cls]) {
|
|
416
|
+
return { kind: "static", decls: COLOR_RULES[cls] };
|
|
417
|
+
}
|
|
418
|
+
if (useColor && PRIMITIVE_COLOR_RULES[cls]) {
|
|
419
|
+
return { kind: "static", decls: PRIMITIVE_COLOR_RULES[cls] };
|
|
420
|
+
}
|
|
421
|
+
if (useTypography) {
|
|
422
|
+
const fontSize = parseFontSize(cls);
|
|
423
|
+
if (fontSize) return { kind: "fontsize", prop: fontSize.prop, value: fontSize.value };
|
|
424
|
+
}
|
|
425
|
+
if (useSpacing) {
|
|
426
|
+
const match = cls.match(/^([a-z]+)-(n)?(\d+(?:d\d+)?)(p|vw|vh)?$/);
|
|
427
|
+
if (match) {
|
|
428
|
+
const [, prefix, neg, num, suffix] = match;
|
|
429
|
+
const rule = SPACING_RULES[prefix];
|
|
430
|
+
if (rule) {
|
|
431
|
+
if (suffix === "p" && !SPACING_PERCENT_ENABLED.has(prefix)) return null;
|
|
432
|
+
if ((suffix === "vw" || suffix === "vh") && !SPACING_VIEWPORT_ENABLED.has(prefix)) return null;
|
|
433
|
+
if (rule.unitless && (suffix || num.includes("d"))) return null;
|
|
434
|
+
if (neg && rule.nonNegative) return null;
|
|
435
|
+
const sign = neg ? "-" : "";
|
|
436
|
+
let unit;
|
|
437
|
+
if (rule.unitless) unit = "";
|
|
438
|
+
else if (suffix === "p") unit = "%";
|
|
439
|
+
else if (suffix === "vw") unit = "vw";
|
|
440
|
+
else if (suffix === "vh") unit = "vh";
|
|
441
|
+
else unit = "px";
|
|
442
|
+
return { kind: "numeric", props: rule.props, value: `${sign}${num.replace("d", ".")}${unit}`, companion: rule.companion };
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return null;
|
|
447
|
+
}
|
|
448
|
+
function rank(base) {
|
|
449
|
+
if (useBorder && BORDER_STYLE_RULES[base]) return 3;
|
|
450
|
+
if (useSpacing && SPACING_STATIC_RULES[base]) return 0;
|
|
451
|
+
const m = base.match(/^([a-z]+)-n?\d/);
|
|
452
|
+
if (useSpacing && m && SPACING_RULES[m[1]]) return 1;
|
|
453
|
+
return 2;
|
|
454
|
+
}
|
|
455
|
+
function generateCSS(classes) {
|
|
456
|
+
const entries = [...classes].map((key) => {
|
|
457
|
+
const bang = key.endsWith("!");
|
|
458
|
+
const base = bang ? key.slice(0, -1) : key;
|
|
459
|
+
const m = base.match(/^([a-z]+)-n?\d/);
|
|
460
|
+
const sub = rank(base) === 1 && m ? SPACING_ORDER.indexOf(m[1]) : 0;
|
|
461
|
+
return { key, base, bang, tier: rank(base), sub };
|
|
462
|
+
});
|
|
463
|
+
entries.sort(
|
|
464
|
+
(x, y) => x.tier - y.tier || x.sub - y.sub || x.base.localeCompare(y.base) || Number(x.bang) - Number(y.bang)
|
|
465
|
+
);
|
|
466
|
+
let css = `/* AUTO-GENERATED by ${PKG} \u2014 do not edit by hand. */
|
|
467
|
+
`;
|
|
468
|
+
if (COLOR_ROOT_VARS) css += COLOR_ROOT_VARS;
|
|
469
|
+
for (const { base, bang } of entries) {
|
|
470
|
+
const parsed = parseClass(base);
|
|
471
|
+
if (!parsed) continue;
|
|
472
|
+
const flag = options.important || bang ? " !important" : "";
|
|
473
|
+
let decls;
|
|
474
|
+
if (parsed.kind === "numeric") {
|
|
475
|
+
const all = parsed.props.map((p) => ` ${p}: ${parsed.value}${flag};`);
|
|
476
|
+
const companion = parsed.companion ? Object.entries(parsed.companion).map(([p, v]) => ` ${p}: ${v}${flag};`) : [];
|
|
477
|
+
decls = [...all, ...companion].join("\n");
|
|
478
|
+
} else if (parsed.kind === "static") {
|
|
479
|
+
decls = Object.entries(parsed.decls).map(([prop, value]) => ` ${prop}: ${value}${flag};`).join("\n");
|
|
480
|
+
} else {
|
|
481
|
+
decls = ` ${parsed.prop}: ${parsed.value}${flag};`;
|
|
482
|
+
}
|
|
483
|
+
css += `.${base}${bang ? "\\!" : ""} {
|
|
484
|
+
${decls}
|
|
485
|
+
}
|
|
486
|
+
`;
|
|
487
|
+
}
|
|
488
|
+
return css;
|
|
489
|
+
}
|
|
490
|
+
function walkDir(dir, exts, out = []) {
|
|
491
|
+
let entries;
|
|
492
|
+
try {
|
|
493
|
+
entries = import_node_fs.default.readdirSync(dir, { withFileTypes: true });
|
|
494
|
+
} catch {
|
|
495
|
+
return out;
|
|
496
|
+
}
|
|
497
|
+
for (const entry of entries) {
|
|
498
|
+
if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
|
|
499
|
+
const full = import_node_path.default.join(dir, entry.name);
|
|
500
|
+
if (entry.isDirectory()) {
|
|
501
|
+
walkDir(full, exts, out);
|
|
502
|
+
} else if (exts.some((e) => entry.name.endsWith(e)) && !exclude.some((x) => full.includes(x))) {
|
|
503
|
+
out.push(full);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return out;
|
|
507
|
+
}
|
|
508
|
+
let root = process.cwd();
|
|
509
|
+
const found = /* @__PURE__ */ new Set();
|
|
510
|
+
let viteServer = null;
|
|
511
|
+
function scanFile(file) {
|
|
512
|
+
let content;
|
|
513
|
+
try {
|
|
514
|
+
content = import_node_fs.default.readFileSync(file, "utf-8");
|
|
515
|
+
} catch {
|
|
516
|
+
return false;
|
|
517
|
+
}
|
|
518
|
+
let changed = false;
|
|
519
|
+
let m;
|
|
520
|
+
CLASS_RE.lastIndex = 0;
|
|
521
|
+
while (m = CLASS_RE.exec(content)) {
|
|
522
|
+
const key = m[1] + (m[2] ?? "");
|
|
523
|
+
if (!found.has(key) && parseClass(m[1])) {
|
|
524
|
+
found.add(key);
|
|
525
|
+
changed = true;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
return changed;
|
|
529
|
+
}
|
|
530
|
+
function scanAll() {
|
|
531
|
+
for (const file of walkDir(import_node_path.default.resolve(root, srcDir), extensions)) scanFile(file);
|
|
532
|
+
scanFile(import_node_path.default.resolve(root, "index.html"));
|
|
533
|
+
}
|
|
534
|
+
function handleFsEvent(file) {
|
|
535
|
+
if (!extensions.some((e) => file.endsWith(e))) return;
|
|
536
|
+
if (exclude.some((x) => file.includes(x))) return;
|
|
537
|
+
const changed = scanFile(file);
|
|
538
|
+
if (changed && viteServer) {
|
|
539
|
+
const mod = viteServer.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ID);
|
|
540
|
+
if (mod) viteServer.moduleGraph.invalidateModule(mod);
|
|
541
|
+
viteServer.ws.send({ type: "full-reload" });
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
return {
|
|
545
|
+
name: PKG,
|
|
546
|
+
configResolved(config) {
|
|
547
|
+
root = config.root;
|
|
548
|
+
},
|
|
549
|
+
buildStart() {
|
|
550
|
+
scanAll();
|
|
551
|
+
},
|
|
552
|
+
resolveId(id) {
|
|
553
|
+
if (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID;
|
|
554
|
+
},
|
|
555
|
+
load(id) {
|
|
556
|
+
if (id === RESOLVED_VIRTUAL_ID) return generateCSS(found);
|
|
557
|
+
},
|
|
558
|
+
configureServer(server) {
|
|
559
|
+
viteServer = server;
|
|
560
|
+
server.watcher.add(import_node_path.default.resolve(root, srcDir));
|
|
561
|
+
server.watcher.on("change", handleFsEvent);
|
|
562
|
+
server.watcher.on("add", handleFsEvent);
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
interface CssModuleOptions {
|
|
4
|
+
srcDir?: string;
|
|
5
|
+
extensions?: string[];
|
|
6
|
+
spacing?: boolean;
|
|
7
|
+
layout?: boolean;
|
|
8
|
+
typography?: boolean;
|
|
9
|
+
cursor?: boolean;
|
|
10
|
+
border?: boolean;
|
|
11
|
+
colorsModule?: Record<string, unknown>;
|
|
12
|
+
primitiveClasses?: boolean;
|
|
13
|
+
exclude?: string[];
|
|
14
|
+
important?: boolean;
|
|
15
|
+
}
|
|
16
|
+
declare function cssModule(options?: CssModuleOptions): Plugin;
|
|
17
|
+
|
|
18
|
+
export { type CssModuleOptions, cssModule as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
interface CssModuleOptions {
|
|
4
|
+
srcDir?: string;
|
|
5
|
+
extensions?: string[];
|
|
6
|
+
spacing?: boolean;
|
|
7
|
+
layout?: boolean;
|
|
8
|
+
typography?: boolean;
|
|
9
|
+
cursor?: boolean;
|
|
10
|
+
border?: boolean;
|
|
11
|
+
colorsModule?: Record<string, unknown>;
|
|
12
|
+
primitiveClasses?: boolean;
|
|
13
|
+
exclude?: string[];
|
|
14
|
+
important?: boolean;
|
|
15
|
+
}
|
|
16
|
+
declare function cssModule(options?: CssModuleOptions): Plugin;
|
|
17
|
+
|
|
18
|
+
export { type CssModuleOptions, cssModule as default };
|