@unocss/transformer-attributify-jsx 66.5.11 → 66.5.12

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.d.mts CHANGED
@@ -966,6 +966,12 @@ interface TransformerAttributifyJsxOptions {
966
966
  */
967
967
  exclude?: FilterPattern;
968
968
  }
969
+ interface AttributifyResolverParams {
970
+ code: MagicString;
971
+ id: string;
972
+ uno: UnoGenerator<object>;
973
+ isBlocked: (matchedRule: string) => boolean;
974
+ }
969
975
  declare function transformerAttributifyJsx(options?: TransformerAttributifyJsxOptions): SourceCodeTransformer;
970
976
  //#endregion
971
- export { FilterPattern, TransformerAttributifyJsxOptions, transformerAttributifyJsx as default };
977
+ export { AttributifyResolverParams, FilterPattern, TransformerAttributifyJsxOptions, transformerAttributifyJsx as default };
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
+ import { toArray } from "@unocss/core";
1
2
  import { parse } from "@babel/parser";
2
3
  import _traverse from "@babel/traverse";
3
- import { toArray } from "@unocss/core";
4
4
 
5
5
  //#region ../../virtual-shared/integration/src/env.ts
6
6
  function getEnvFlags() {
@@ -13,8 +13,71 @@ function getEnvFlags() {
13
13
  }
14
14
 
15
15
  //#endregion
16
- //#region src/index.ts
16
+ //#region src/resolver/babel.ts
17
17
  const traverse = _traverse.default || _traverse;
18
+ async function attributifyJsxBabelResolver(params) {
19
+ const { code, uno, isBlocked } = params;
20
+ const tasks = [];
21
+ const ast = parse(code.toString(), {
22
+ sourceType: "module",
23
+ plugins: ["jsx", "typescript"]
24
+ });
25
+ if (ast.errors?.length) throw new Error(`Babel parse errors:\n${ast.errors.join("\n")}`);
26
+ traverse(ast, { JSXAttribute(path) {
27
+ if (path.node.value === null) {
28
+ const attr = path.node.name.type === "JSXNamespacedName" ? `${path.node.name.namespace.name}:${path.node.name.name.name}` : path.node.name.name;
29
+ if (isBlocked(attr)) return;
30
+ tasks.push(uno.parseToken(attr).then((matched) => {
31
+ if (matched) code.appendRight(path.node.end, "=\"\"");
32
+ }));
33
+ }
34
+ } });
35
+ await Promise.all(tasks);
36
+ }
37
+
38
+ //#endregion
39
+ //#region src/resolver/regex.ts
40
+ const elementRE = /<([^/?<>0-9$_!][^\s>]*)\s+((?:"[^"]*"|'[^"]*'|(\{[^}]*\})|[^{>])+)>/g;
41
+ const attributeRE = /(?<![~`!$%^&*()_+\-=[{;':"|,.<>/?])([a-z()#][[?\w\-:()#%\]]*)(?:\s*=\s*('[^']*'|"[^"]*"|\S+))?|\{[^}]*\}/gi;
42
+ const valuedAttributeRE = /((?!\d|-{2}|-\d)[\w\u00A0-\uFFFF:!%.~<-]+)=(?:"[^"]*"|'[^']*'|(\{)((?:[`(][^`)]*[`)]|[^}])+)(\}))/g;
43
+ async function attributifyJsxRegexResolver(params) {
44
+ const { code, uno, isBlocked } = params;
45
+ const tasks = [];
46
+ const attributifyPrefix = uno.config.presets.find((i) => i.name === "@unocss/preset-attributify")?.options?.prefix ?? "un-";
47
+ for (const item of Array.from(code.original.matchAll(elementRE))) {
48
+ let attributifyPart = item[2];
49
+ if (valuedAttributeRE.test(attributifyPart)) attributifyPart = attributifyPart.replace(valuedAttributeRE, (match, _, dynamicFlagStart) => {
50
+ if (!dynamicFlagStart) return " ".repeat(match.length);
51
+ let preLastModifierIndex = 0;
52
+ let temp = match;
53
+ for (const _item of match.matchAll(elementRE)) {
54
+ const attrAttributePart = _item[2];
55
+ if (valuedAttributeRE.test(attrAttributePart)) attrAttributePart.replace(valuedAttributeRE, (m) => " ".repeat(m.length));
56
+ const pre = temp.slice(0, preLastModifierIndex) + " ".repeat(_item.index + _item[0].indexOf(_item[2]) - preLastModifierIndex) + attrAttributePart;
57
+ temp = pre + " ".repeat(_item.input.length - pre.length);
58
+ preLastModifierIndex = pre.length;
59
+ }
60
+ if (preLastModifierIndex !== 0) return temp;
61
+ return " ".repeat(match.length);
62
+ });
63
+ for (const attr of attributifyPart.matchAll(attributeRE)) {
64
+ const matchedRule = attr[0];
65
+ if (matchedRule.includes("=") || isBlocked(matchedRule)) continue;
66
+ const updatedMatchedRule = matchedRule.startsWith(attributifyPrefix) ? matchedRule.slice(attributifyPrefix.length) : matchedRule;
67
+ tasks.push(uno.parseToken(updatedMatchedRule).then((matched) => {
68
+ if (matched) {
69
+ const startIdx = (item.index || 0) + (attr.index || 0) + item[0].indexOf(item[2]);
70
+ const endIdx = startIdx + matchedRule.length;
71
+ code.overwrite(startIdx, endIdx, `${matchedRule}=""`);
72
+ }
73
+ }));
74
+ }
75
+ }
76
+ await Promise.all(tasks);
77
+ }
78
+
79
+ //#endregion
80
+ //#region src/index.ts
18
81
  function createFilter(include, exclude) {
19
82
  const includePattern = toArray(include || []);
20
83
  const excludePattern = toArray(exclude || []);
@@ -35,24 +98,22 @@ function transformerAttributifyJsx(options = {}) {
35
98
  name: "@unocss/transformer-attributify-jsx",
36
99
  enforce: "pre",
37
100
  idFilter: createFilter(options.include || [/\.[jt]sx$/, /\.mdx$/], options.exclude || []),
38
- async transform(code, _, { uno }) {
101
+ async transform(code, id, { uno }) {
39
102
  try {
40
103
  if (getEnvFlags().isVSCode) return;
41
104
  } catch {}
42
- const tasks = [];
43
- traverse(parse(code.toString(), {
44
- sourceType: "module",
45
- plugins: ["jsx", "typescript"]
46
- }), { JSXAttribute(path) {
47
- if (path.node.value === null) {
48
- const attr = path.node.name.type === "JSXNamespacedName" ? `${path.node.name.namespace.name}:${path.node.name.name.name}` : path.node.name.name;
49
- if (isBlocked(attr)) return;
50
- tasks.push(uno.parseToken(attr).then((matched) => {
51
- if (matched) code.appendRight(path.node.end, "=\"\"");
52
- }));
53
- }
54
- } });
55
- await Promise.all(tasks);
105
+ const params = {
106
+ code,
107
+ id,
108
+ uno,
109
+ isBlocked
110
+ };
111
+ try {
112
+ await attributifyJsxBabelResolver(params);
113
+ } catch (error) {
114
+ console.warn(`[@unocss/transformer-attributify-jsx]: Babel resolver failed for "${id}", falling back to regex resolver:`, error);
115
+ await attributifyJsxRegexResolver(params);
116
+ }
56
117
  }
57
118
  };
58
119
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@unocss/transformer-attributify-jsx",
3
3
  "type": "module",
4
- "version": "66.5.11",
4
+ "version": "66.5.12",
5
5
  "description": "Support valueless attributify in JSX/TSX.",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -35,7 +35,7 @@
35
35
  "dependencies": {
36
36
  "@babel/parser": "7.27.7",
37
37
  "@babel/traverse": "7.27.7",
38
- "@unocss/core": "66.5.11"
38
+ "@unocss/core": "66.5.12"
39
39
  },
40
40
  "devDependencies": {
41
41
  "magic-string": "^0.30.21"