@netoyed/ux4g-design-system-v3-postcss 1.0.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/dist/index.js ADDED
@@ -0,0 +1,361 @@
1
+ // index.js
2
+ import fg from "fast-glob";
3
+ import fs from "fs";
4
+
5
+ // ../core/jit/registry.js
6
+ var registry = {
7
+ // --- Spacing ---
8
+ "p": { type: "space", property: "padding" },
9
+ "pt": { type: "space", property: "padding-top" },
10
+ "pr": { type: "space", property: "padding-right" },
11
+ "pb": { type: "space", property: "padding-bottom" },
12
+ "pl": { type: "space", property: "padding-left" },
13
+ "px": { type: "space", property: ["padding-left", "padding-right"] },
14
+ "py": { type: "space", property: ["padding-top", "padding-bottom"] },
15
+ "m": { type: "space", property: "margin" },
16
+ "mt": { type: "space", property: "margin-top" },
17
+ "mr": { type: "space", property: "margin-right" },
18
+ "mb": { type: "space", property: "margin-bottom" },
19
+ "ml": { type: "space", property: "margin-left" },
20
+ "mx": { type: "space", property: ["margin-left", "margin-right"] },
21
+ "my": { type: "space", property: ["margin-top", "margin-bottom"] },
22
+ // --- Colors ---
23
+ "text": { type: "color", property: "color" },
24
+ "bg": { type: "color", property: "background-color" },
25
+ "border": { type: "color", property: "border-color" },
26
+ // --- Typography ---
27
+ "font": { type: "fontDetail", property: "font-weight" },
28
+ "text-size": { type: "text", property: "font-size" },
29
+ "leading": { type: "value", property: "line-height" },
30
+ "tracking": { type: "value", property: "letter-spacing" },
31
+ "align": { type: "static", property: "text-align" },
32
+ // text-center
33
+ // --- Layout ---
34
+ "flex": { type: "static", property: "display", value: "flex" },
35
+ "inline-flex": { type: "static", property: "display", value: "inline-flex" },
36
+ "grid": { type: "static", property: "display", value: "grid" },
37
+ "hidden": { type: "static", property: "display", value: "none" },
38
+ "block": { type: "static", property: "display", value: "block" },
39
+ "inline-block": { type: "static", property: "display", value: "inline-block" },
40
+ "items": { type: "static", property: "align-items" },
41
+ // start, end, center, baseline, stretch
42
+ "justify": { type: "static", property: "justify-content" },
43
+ // start, end, center, between, around, evenly
44
+ "self": { type: "static", property: "align-self" },
45
+ "flex-col": { type: "static", property: "flex-direction", value: "column" },
46
+ "flex-row": { type: "static", property: "flex-direction", value: "row" },
47
+ "flex-wrap": { type: "static", property: "flex-wrap", value: "wrap" },
48
+ "flex-nowrap": { type: "static", property: "flex-wrap", value: "nowrap" },
49
+ "gap": { type: "space", property: "gap" },
50
+ "gap-x": { type: "space", property: "column-gap" },
51
+ "gap-y": { type: "space", property: "row-gap" },
52
+ // --- Sizing ---
53
+ "w": { type: "size", property: "width" },
54
+ "h": { type: "size", property: "height" },
55
+ "min-w": { type: "size", property: "min-width" },
56
+ "min-h": { type: "size", property: "min-height" },
57
+ "max-w": { type: "size", property: "max-width" },
58
+ "max-h": { type: "size", property: "max-height" },
59
+ // --- Borders & Effects ---
60
+ "rounded": { type: "radius", property: "border-radius" },
61
+ "shadow": { type: "shadow", property: "box-shadow" },
62
+ "opacity": { type: "value", property: "opacity" },
63
+ "z": { type: "zIndex", property: "z-index" },
64
+ // --- Position ---
65
+ "absolute": { type: "static", property: "position", value: "absolute" },
66
+ "relative": { type: "static", property: "position", value: "relative" },
67
+ "fixed": { type: "static", property: "position", value: "fixed" },
68
+ "top": { type: "space", property: "top" },
69
+ "right": { type: "space", property: "right" },
70
+ "bottom": { type: "space", property: "bottom" },
71
+ "left": { type: "space", property: "left" }
72
+ };
73
+
74
+ // ../core/jit/generator.js
75
+ function generateUtility(className, config) {
76
+ let bp = null;
77
+ let util = className;
78
+ if (className.includes(":")) {
79
+ [bp, util] = className.split(":");
80
+ }
81
+ let css = "";
82
+ if (!util.startsWith(config.prefix)) return null;
83
+ const coreUtil = util.replace(config.prefix, "");
84
+ for (const [key, def] of Object.entries(registry)) {
85
+ const prefix = `${key}-`;
86
+ if (coreUtil.startsWith(prefix)) {
87
+ const value = coreUtil.slice(prefix.length);
88
+ let varName = "";
89
+ if (def.type === "space") varName = `var(--${config.prefix}space-${value})`;
90
+ else if (def.type === "color") varName = `var(--${config.prefix}color-${value})`;
91
+ else if (def.type === "radius") varName = `var(--${config.prefix}radius-${value || "DEFAULT"})`;
92
+ else if (def.type === "shadow") varName = `var(--${config.prefix}shadow-${value || "DEFAULT"})`;
93
+ else if (def.type === "zIndex") varName = `var(--${config.prefix}zIndex-${value})`;
94
+ else if (def.type === "fontDetail") varName = `var(--${config.prefix}fontWeight-${value})`;
95
+ else if (def.type === "static") {
96
+ if (def.value) {
97
+ if (value !== "" && !def.allowValue) continue;
98
+ varName = def.value;
99
+ } else {
100
+ varName = value;
101
+ }
102
+ } else if (def.type === "size") {
103
+ if (config.theme.spacing[value]) {
104
+ varName = `var(--${config.prefix}space-${value})`;
105
+ } else if (value.includes("/")) {
106
+ const [num, den] = value.split("/");
107
+ varName = `${parseInt(num) / parseInt(den) * 100}%`;
108
+ } else {
109
+ continue;
110
+ }
111
+ } else continue;
112
+ const props = Array.isArray(def.property) ? def.property : [def.property];
113
+ const decls = def.type === "static" && def.value ? varName : props.map((p) => `${p}:${varName}`).join(";");
114
+ css = `.${escape(className)}{${decls};}`;
115
+ break;
116
+ }
117
+ }
118
+ if (!css) return null;
119
+ if (bp) {
120
+ const size = config.breakpoints[bp];
121
+ return `@media (min-width:${size}){${css}}`;
122
+ }
123
+ return css;
124
+ }
125
+ function escape(cls) {
126
+ return cls.replace(/:/g, "\\:");
127
+ }
128
+
129
+ // ../core/config/defaultConfig.js
130
+ var defaultConfig = {
131
+ /**
132
+ * --------------------------------------------------
133
+ * CORE
134
+ * --------------------------------------------------
135
+ */
136
+ prefix: "ux4g-",
137
+ /**
138
+ * dev | build | cdn
139
+ * NOTE: CLI command will override this
140
+ */
141
+ mode: "build",
142
+ /**
143
+ * --------------------------------------------------
144
+ * CONTENT (used for purge / JIT)
145
+ * --------------------------------------------------
146
+ */
147
+ content: [
148
+ "./index.html",
149
+ "./src/**/*.{js,ts,jsx,tsx,vue,html}",
150
+ "./pages/**/*.{js,ts,jsx,tsx}",
151
+ "./components/**/*.{js,ts,jsx,tsx}",
152
+ "./**/*.php"
153
+ ],
154
+ /**
155
+ * --------------------------------------------------
156
+ * THEME (tokens)
157
+ * --------------------------------------------------
158
+ */
159
+ theme: {
160
+ colors: {
161
+ primary: {
162
+ 50: "#EFF6FF",
163
+ 500: "#3B82F6",
164
+ 700: "#1D4ED8"
165
+ },
166
+ secondary: {
167
+ 500: "#9333EA"
168
+ },
169
+ danger: {
170
+ 500: "#EF4444"
171
+ }
172
+ },
173
+ spacing: {
174
+ 0: "0px",
175
+ 1: "4px",
176
+ 2: "8px",
177
+ 4: "16px",
178
+ 6: "24px",
179
+ 8: "32px"
180
+ },
181
+ fontSize: {
182
+ xs: "12px",
183
+ sm: "14px",
184
+ md: "16px",
185
+ lg: "18px",
186
+ xl: "20px"
187
+ },
188
+ fontWeight: {
189
+ regular: 400,
190
+ medium: 500,
191
+ bold: 700
192
+ },
193
+ radius: {
194
+ sm: "4px",
195
+ md: "8px",
196
+ lg: "12px",
197
+ xl: "16px"
198
+ },
199
+ shadow: {
200
+ sm: "0 1px 2px rgba(0,0,0,0.05)",
201
+ md: "0 4px 6px rgba(0,0,0,0.1)"
202
+ },
203
+ zIndex: {
204
+ dropdown: 1e3,
205
+ modal: 1100,
206
+ toast: 1200
207
+ }
208
+ },
209
+ /**
210
+ * --------------------------------------------------
211
+ * RESPONSIVE
212
+ * --------------------------------------------------
213
+ */
214
+ breakpoints: {
215
+ sm: "640px",
216
+ md: "768px",
217
+ lg: "1024px",
218
+ xl: "1280px"
219
+ },
220
+ /**
221
+ * --------------------------------------------------
222
+ * DARK MODE / THEMES
223
+ * --------------------------------------------------
224
+ */
225
+ darkMode: {
226
+ enabled: true,
227
+ strategy: "data-attribute",
228
+ // class | data-attribute
229
+ attribute: "data-theme",
230
+ themes: {
231
+ light: "light",
232
+ dark: "dark"
233
+ }
234
+ },
235
+ /**
236
+ * --------------------------------------------------
237
+ * SAFELIST (dynamic classes)
238
+ * --------------------------------------------------
239
+ */
240
+ safelist: [],
241
+ /**
242
+ * --------------------------------------------------
243
+ * COMPONENTS
244
+ * --------------------------------------------------
245
+ */
246
+ components: {
247
+ button: true,
248
+ card: true,
249
+ input: true,
250
+ modal: false
251
+ },
252
+ /**
253
+ * --------------------------------------------------
254
+ * PLUGINS
255
+ * --------------------------------------------------
256
+ */
257
+ plugins: [],
258
+ /**
259
+ * --------------------------------------------------
260
+ * OUTPUT
261
+ * --------------------------------------------------
262
+ */
263
+ output: {
264
+ dir: "dist",
265
+ file: "ux4g.css",
266
+ minify: true,
267
+ sourceMap: false
268
+ }
269
+ };
270
+
271
+ // ../core/config/preflight.js
272
+ var preflight = `
273
+ /* UX4G Preflight (Reset) */
274
+ *, ::before, ::after { box-sizing: border-box; border-width: 0; border-style: solid; border-color: currentColor; }
275
+ html { line-height: 1.5; -webkit-text-size-adjust: 100%; -moz-tab-size: 4; tab-size: 4; font-family: system-ui, sans-serif; }
276
+ body { margin: 0; line-height: inherit; }
277
+ hr { height: 0; color: inherit; border-top-width: 1px; }
278
+ abbr:where([title]) { text-decoration: underline dotted; }
279
+ h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; }
280
+ a { color: inherit; text-decoration: inherit; }
281
+ b, strong { font-weight: bolder; }
282
+ code, kbd, samp, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 1em; }
283
+ small { font-size: 80%; }
284
+ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
285
+ sub { bottom: -0.25em; }
286
+ sup { top: -0.5em; }
287
+ table { text-indent: 0; border-color: inherit; border-collapse: collapse; }
288
+ button, input, optgroup, select, textarea { font-family: inherit; font-size: 100%; line-height: inherit; color: inherit; margin: 0; padding: 0; }
289
+ button, select { text-transform: none; }
290
+ button, [type='button'], [type='reset'], [type='submit'] { -webkit-appearance: button; background-color: transparent; background-image: none; }
291
+ :-moz-focusring { outline: auto; }
292
+ :-moz-ui-invalid { box-shadow: none; }
293
+ progress { vertical-align: baseline; }
294
+ ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; }
295
+ [type='search'] { -webkit-appearance: textfield; outline-offset: -2px; }
296
+ ::-webkit-search-decoration { -webkit-appearance: none; }
297
+ ::-webkit-file-upload-button { -webkit-appearance: button; font: inherit; }
298
+ summary { display: list-item; }
299
+ blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre { margin: 0; }
300
+ fieldset { margin: 0; padding: 0; }
301
+ legend { padding: 0; }
302
+ ol, ul, menu { list-style: none; margin: 0; padding: 0; }
303
+ textarea { resize: vertical; }
304
+ input::placeholder, textarea::placeholder { opacity: 1; color: #9ca3af; }
305
+ button, [role="button"] { cursor: pointer; }
306
+ :disabled { cursor: default; }
307
+ img, svg, video, canvas, audio, iframe, embed, object { display: block; vertical-align: middle; }
308
+ img, video { max-width: 100%; height: auto; }
309
+ [hidden] { display: none; }
310
+ `;
311
+
312
+ // index.js
313
+ function deepMerge(target, source) {
314
+ if (typeof source !== "object" || source === null) return source;
315
+ const result = { ...target };
316
+ for (const key of Object.keys(source)) {
317
+ if (Array.isArray(source[key])) {
318
+ result[key] = source[key];
319
+ } else if (typeof source[key] === "object" && typeof target[key] === "object") {
320
+ result[key] = deepMerge(target[key], source[key]);
321
+ } else {
322
+ result[key] = source[key];
323
+ }
324
+ }
325
+ return result;
326
+ }
327
+ var index_default = (opts = {}) => {
328
+ return {
329
+ postcssPlugin: "ux4g",
330
+ async Once(root, { result }) {
331
+ let config = deepMerge(defaultConfig, opts);
332
+ config.prefix = "ux4g-";
333
+ const files = await fg(config.content);
334
+ const foundClasses = /* @__PURE__ */ new Set();
335
+ const prefix = config.prefix.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
336
+ const CLASS_REGEX = new RegExp(`(sm:|md:|lg:|xl:)?${prefix}[a-z0-9\\-]+`, "g");
337
+ for (const file of files) {
338
+ const content = fs.readFileSync(file, "utf8");
339
+ const matches = content.match(CLASS_REGEX);
340
+ if (matches) matches.forEach((c) => foundClasses.add(c));
341
+ }
342
+ let utilitiesCSS = "";
343
+ for (const cls of foundClasses) {
344
+ const css = generateUtility(cls, config);
345
+ if (css) utilitiesCSS += css + "\n";
346
+ }
347
+ root.walkAtRules("ux4g", (rule) => {
348
+ if (rule.params === "base") {
349
+ rule.replaceWith(preflight);
350
+ } else if (rule.params === "utilities") {
351
+ rule.replaceWith(utilitiesCSS);
352
+ }
353
+ });
354
+ }
355
+ };
356
+ };
357
+ var postcss = true;
358
+ export {
359
+ index_default as default,
360
+ postcss
361
+ };
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@netoyed/ux4g-design-system-v3-postcss",
3
+ "version": "1.0.0",
4
+ "description": "PostCSS plugin for UX4G Design System",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.cjs"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup index.js --format cjs,esm --dts --clean --platform node",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "devDependencies": {
23
+ "tsup": "^8.0.0",
24
+ "typescript": "^5.9.3"
25
+ },
26
+ "dependencies": {
27
+ "fast-glob": "^3.0.0",
28
+ "postcss": "^8.0.0"
29
+ }
30
+ }