@decantr/css 1.0.5 → 2.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.
Files changed (2) hide show
  1. package/dist/index.js +91 -9
  2. package/package.json +7 -4
package/dist/index.js CHANGED
@@ -786,6 +786,36 @@ function semanticColorDecl(prop, rawToken) {
786
786
  }
787
787
  return `${prop}:${value}`;
788
788
  }
789
+ function compactSemanticColorToken(name, prefix) {
790
+ if (!name.startsWith(prefix) || name.length === prefix.length) return null;
791
+ const token = name.slice(prefix.length);
792
+ const slashIndex = token.indexOf("/");
793
+ if (slashIndex !== -1) {
794
+ if (slashIndex === 0 || slashIndex === token.length - 1) return null;
795
+ if (token.indexOf("/", slashIndex + 1) !== -1) return null;
796
+ if (!isCompactColorName(token.slice(0, slashIndex))) return null;
797
+ if (!isAsciiDigitString(token.slice(slashIndex + 1))) return null;
798
+ return token;
799
+ }
800
+ return isCompactColorName(token) ? token : null;
801
+ }
802
+ function isCompactColorName(value) {
803
+ if (!value) return false;
804
+ for (const char of value) {
805
+ const codePoint = char.charCodeAt(0);
806
+ const isAllowed = codePoint >= 48 && codePoint <= 57 || codePoint >= 65 && codePoint <= 90 || codePoint >= 97 && codePoint <= 122 || char === "-";
807
+ if (!isAllowed) return false;
808
+ }
809
+ return true;
810
+ }
811
+ function isAsciiDigitString(value) {
812
+ if (!value) return false;
813
+ for (const char of value) {
814
+ const codePoint = char.charCodeAt(0);
815
+ if (codePoint < 48 || codePoint > 57) return false;
816
+ }
817
+ return true;
818
+ }
789
819
  function resolveTailwindishDecl(name) {
790
820
  if (TAILWIND_DIRECT[name]) return TAILWIND_DIRECT[name];
791
821
  const arbitraryMatch = name.match(/^([a-z]+(?:-[a-z]+)*)-\[([^\]]+)\]$/);
@@ -874,15 +904,15 @@ function resolveTailwindishDecl(name) {
874
904
  const decl = semanticColorDecl("border-color", borderColorMatch[1]);
875
905
  if (decl) return decl;
876
906
  }
877
- const compactBorderColorMatch = name.match(/^border([a-zA-Z0-9-]+\/?\d*)$/);
878
- if (compactBorderColorMatch) {
879
- const decl = semanticColorDecl("border-color", compactBorderColorMatch[1]);
907
+ const compactBorderColor = compactSemanticColorToken(name, "border");
908
+ if (compactBorderColor) {
909
+ const decl = semanticColorDecl("border-color", compactBorderColor);
880
910
  if (decl) return decl;
881
911
  }
882
- const compactFgMatch = name.match(/^fg([a-zA-Z0-9-]+\/?\d*)$/);
883
- if (compactFgMatch) return semanticColorDecl("color", compactFgMatch[1]);
884
- const compactBgMatch = name.match(/^bg([a-zA-Z0-9-]+\/?\d*)$/);
885
- if (compactBgMatch) return semanticColorDecl("background", compactBgMatch[1]);
912
+ const compactFg = compactSemanticColorToken(name, "fg");
913
+ if (compactFg) return semanticColorDecl("color", compactFg);
914
+ const compactBg = compactSemanticColorToken(name, "bg");
915
+ if (compactBg) return semanticColorDecl("background", compactBg);
886
916
  const borderSideWidthMatch = name.match(/^border-([trbl])-(\d+)$/);
887
917
  if (borderSideWidthMatch) {
888
918
  const side = { t: "top", r: "right", b: "bottom", l: "left" }[borderSideWidthMatch[1]];
@@ -1316,7 +1346,33 @@ function injectMediaQuery(className, declaration, query) {
1316
1346
  scheduleFlush();
1317
1347
  }
1318
1348
  function escapeSelector(className) {
1319
- return className.replace(/:/g, "\\:").replace(/\./g, "\\.").replace(/\//g, "\\/").replace(/\[/g, "\\[").replace(/\]/g, "\\]").replace(/#/g, "\\#").replace(/%/g, "\\%").replace(/\(/g, "\\(").replace(/\)/g, "\\)").replace(/,/g, "\\,").replace(/\+/g, "\\+");
1349
+ const chars = Array.from(className);
1350
+ let escaped = "";
1351
+ for (let index = 0; index < chars.length; index += 1) {
1352
+ const char = chars[index];
1353
+ const codePoint = char.codePointAt(0) ?? 0;
1354
+ const firstChar = chars[0];
1355
+ const isControl = codePoint >= 1 && codePoint <= 31 || codePoint === 127;
1356
+ const needsNumericEscape = isControl || index === 0 && isAsciiDigit(codePoint) || index === 1 && firstChar === "-" && isAsciiDigit(codePoint);
1357
+ if (codePoint === 0) {
1358
+ escaped += "\uFFFD";
1359
+ } else if (needsNumericEscape) {
1360
+ escaped += `\\${codePoint.toString(16)} `;
1361
+ } else if (index === 0 && char === "-" && chars.length === 1) {
1362
+ escaped += "\\-";
1363
+ } else if (isCssNameCodePoint(codePoint)) {
1364
+ escaped += char;
1365
+ } else {
1366
+ escaped += `\\${char}`;
1367
+ }
1368
+ }
1369
+ return escaped;
1370
+ }
1371
+ function isAsciiDigit(codePoint) {
1372
+ return codePoint >= 48 && codePoint <= 57;
1373
+ }
1374
+ function isCssNameCodePoint(codePoint) {
1375
+ return codePoint >= 128 || codePoint === 45 || codePoint === 95 || isAsciiDigit(codePoint) || codePoint >= 65 && codePoint <= 90 || codePoint >= 97 && codePoint <= 122;
1320
1376
  }
1321
1377
  function extractCSS() {
1322
1378
  flushBuffers();
@@ -1500,7 +1556,33 @@ function resolveAtom(atomPart) {
1500
1556
  return null;
1501
1557
  }
1502
1558
  function escapeClass(cls) {
1503
- return cls.replace(/:/g, "\\:").replace(/\./g, "\\.").replace(/\//g, "\\/").replace(/\[/g, "\\[").replace(/\]/g, "\\]").replace(/#/g, "\\#").replace(/%/g, "\\%").replace(/\(/g, "\\(").replace(/\)/g, "\\)").replace(/,/g, "\\,").replace(/\+/g, "\\+");
1559
+ const chars = Array.from(cls);
1560
+ let escaped = "";
1561
+ for (let index = 0; index < chars.length; index += 1) {
1562
+ const char = chars[index];
1563
+ const codePoint = char.codePointAt(0) ?? 0;
1564
+ const firstChar = chars[0];
1565
+ const isControl = codePoint >= 1 && codePoint <= 31 || codePoint === 127;
1566
+ const needsNumericEscape = isControl || index === 0 && isAsciiDigit2(codePoint) || index === 1 && firstChar === "-" && isAsciiDigit2(codePoint);
1567
+ if (codePoint === 0) {
1568
+ escaped += "\uFFFD";
1569
+ } else if (needsNumericEscape) {
1570
+ escaped += `\\${codePoint.toString(16)} `;
1571
+ } else if (index === 0 && char === "-" && chars.length === 1) {
1572
+ escaped += "\\-";
1573
+ } else if (isCssNameCodePoint2(codePoint)) {
1574
+ escaped += char;
1575
+ } else {
1576
+ escaped += `\\${char}`;
1577
+ }
1578
+ }
1579
+ return escaped;
1580
+ }
1581
+ function isAsciiDigit2(codePoint) {
1582
+ return codePoint >= 48 && codePoint <= 57;
1583
+ }
1584
+ function isCssNameCodePoint2(codePoint) {
1585
+ return codePoint >= 128 || codePoint === 45 || codePoint === 95 || isAsciiDigit2(codePoint) || codePoint >= 65 && codePoint <= 90 || codePoint >= 97 && codePoint <= 122;
1504
1586
  }
1505
1587
  function css(...classes) {
1506
1588
  const result = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decantr/css",
3
- "version": "1.0.5",
3
+ "version": "2.0.0",
4
4
  "description": "Framework-agnostic CSS atom runtime for Decantr projects",
5
5
  "author": "Decantr AI",
6
6
  "bugs": {
@@ -24,6 +24,9 @@
24
24
  "files": [
25
25
  "dist"
26
26
  ],
27
+ "engines": {
28
+ "node": ">=20"
29
+ },
27
30
  "publishConfig": {
28
31
  "access": "public"
29
32
  },
@@ -36,10 +39,10 @@
36
39
  ],
37
40
  "license": "MIT",
38
41
  "devDependencies": {
39
- "jsdom": "^26.0.0",
42
+ "jsdom": "^29.1.1",
40
43
  "tsup": "^8.0.0",
41
- "typescript": "^5.0.0",
42
- "vitest": "^3.0.0"
44
+ "typescript": "^6.0.3",
45
+ "vitest": "^4.1.5"
43
46
  },
44
47
  "scripts": {
45
48
  "build": "tsup src/index.ts --format esm --dts",