@yahoo/uds 3.116.1 → 3.116.3
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/components/Scrim.cjs +0 -2
- package/dist/components/Scrim.js +0 -2
- package/dist/components/client/BottomSheet/BottomSheet.cjs +37 -8
- package/dist/components/client/BottomSheet/BottomSheet.js +38 -9
- package/dist/components/client/BottomSheet/BottomSheetContent.cjs +4 -2
- package/dist/components/client/BottomSheet/BottomSheetContent.js +4 -2
- package/dist/components/client/BottomSheet/BottomSheetInternalContext.cjs +15 -0
- package/dist/components/client/BottomSheet/BottomSheetInternalContext.d.cts +12 -0
- package/dist/components/client/BottomSheet/BottomSheetInternalContext.d.ts +12 -0
- package/dist/components/client/BottomSheet/BottomSheetInternalContext.js +12 -0
- package/dist/styles/styler.d.cts +85 -85
- package/dist/styles/styler.d.ts +85 -85
- package/dist/tailwind/dist/css/generate.cjs +6 -0
- package/dist/tailwind/dist/css/generate.helpers.cjs +5 -1
- package/dist/tailwind/dist/css/generate.helpers.js +5 -1
- package/dist/tailwind/dist/css/generate.js +6 -0
- package/dist/tailwind/dist/css/nodeUtils.cjs +2 -1
- package/dist/tailwind/dist/css/nodeUtils.js +2 -1
- package/dist/tailwind/dist/purger/optimized/ast/expressions.cjs +103 -1
- package/dist/tailwind/dist/purger/optimized/ast/expressions.js +102 -2
- package/dist/tailwind/dist/purger/optimized/ast/jsx.cjs +7 -1
- package/dist/tailwind/dist/purger/optimized/ast/jsx.js +7 -1
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.cjs +18 -13
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.js +18 -13
- package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.cjs +2 -1
- package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.js +2 -1
- package/dist/uds/generated/componentData.cjs +1124 -1105
- package/dist/uds/generated/componentData.js +1077 -1064
- package/dist/uds/generated/tailwindPurge.cjs +7 -7
- package/dist/uds/generated/tailwindPurge.js +7 -7
- package/generated/componentData.json +1610 -1595
- package/generated/tailwindPurge.ts +2 -2
- package/package.json +1 -1
|
@@ -1,8 +1,105 @@
|
|
|
1
1
|
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
-
import
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import { Node, Project, SyntaxKind, ts } from "ts-morph";
|
|
3
5
|
|
|
4
6
|
//#region ../tailwind/dist/purger/optimized/ast/expressions.js
|
|
5
7
|
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
8
|
+
const importedSourceProject = new Project({ useInMemoryFileSystem: true });
|
|
9
|
+
const importedSourceFileCache = /* @__PURE__ */ new Map();
|
|
10
|
+
const tsConfigPathCache = /* @__PURE__ */ new Map();
|
|
11
|
+
const compilerOptionsCache = /* @__PURE__ */ new Map();
|
|
12
|
+
const hasImportQuery = (moduleSpecifier) => moduleSpecifier.includes("?");
|
|
13
|
+
const isExistingFile = (candidate) => fs.existsSync(candidate) && fs.statSync(candidate).isFile();
|
|
14
|
+
const resolveRelativeImportPath = (sourceFilePath, moduleSpecifier) => {
|
|
15
|
+
if (!path.isAbsolute(sourceFilePath) || !moduleSpecifier.startsWith(".") || hasImportQuery(moduleSpecifier)) return null;
|
|
16
|
+
const basePath = path.resolve(path.dirname(sourceFilePath), moduleSpecifier);
|
|
17
|
+
return [
|
|
18
|
+
basePath,
|
|
19
|
+
`${basePath}.ts`,
|
|
20
|
+
`${basePath}.tsx`,
|
|
21
|
+
`${basePath}.js`,
|
|
22
|
+
`${basePath}.jsx`,
|
|
23
|
+
path.join(basePath, "index.ts"),
|
|
24
|
+
path.join(basePath, "index.tsx"),
|
|
25
|
+
path.join(basePath, "index.js"),
|
|
26
|
+
path.join(basePath, "index.jsx")
|
|
27
|
+
].find((candidate) => isExistingFile(candidate)) ?? null;
|
|
28
|
+
};
|
|
29
|
+
const findNearestTypeScriptConfig = (sourceFilePath) => {
|
|
30
|
+
const sourceDir = path.dirname(sourceFilePath);
|
|
31
|
+
const cached = tsConfigPathCache.get(sourceDir);
|
|
32
|
+
if (cached !== void 0) return cached;
|
|
33
|
+
let currentDir = sourceDir;
|
|
34
|
+
while (true) {
|
|
35
|
+
const tsConfigPath = path.join(currentDir, "tsconfig.json");
|
|
36
|
+
if (isExistingFile(tsConfigPath)) {
|
|
37
|
+
tsConfigPathCache.set(sourceDir, tsConfigPath);
|
|
38
|
+
return tsConfigPath;
|
|
39
|
+
}
|
|
40
|
+
const jsConfigPath = path.join(currentDir, "jsconfig.json");
|
|
41
|
+
if (isExistingFile(jsConfigPath)) {
|
|
42
|
+
tsConfigPathCache.set(sourceDir, jsConfigPath);
|
|
43
|
+
return jsConfigPath;
|
|
44
|
+
}
|
|
45
|
+
const parentDir = path.dirname(currentDir);
|
|
46
|
+
if (parentDir === currentDir) {
|
|
47
|
+
tsConfigPathCache.set(sourceDir, null);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
currentDir = parentDir;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const getCompilerOptionsForSourceFile = (sourceFilePath) => {
|
|
54
|
+
const configPath = findNearestTypeScriptConfig(sourceFilePath);
|
|
55
|
+
if (!configPath) return null;
|
|
56
|
+
const cached = compilerOptionsCache.get(configPath);
|
|
57
|
+
if (cached !== void 0) return cached;
|
|
58
|
+
const readResult = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
59
|
+
if (readResult.error) {
|
|
60
|
+
compilerOptionsCache.set(configPath, null);
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const parsed = ts.parseJsonConfigFileContent(readResult.config, ts.sys, path.dirname(configPath));
|
|
64
|
+
const compilerOptions = parsed.options.paths && !parsed.options.baseUrl ? {
|
|
65
|
+
...parsed.options,
|
|
66
|
+
baseUrl: path.dirname(configPath)
|
|
67
|
+
} : parsed.options;
|
|
68
|
+
compilerOptionsCache.set(configPath, compilerOptions);
|
|
69
|
+
return compilerOptions;
|
|
70
|
+
};
|
|
71
|
+
const resolveConfigImportPath = (sourceFilePath, moduleSpecifier) => {
|
|
72
|
+
if (hasImportQuery(moduleSpecifier)) return null;
|
|
73
|
+
const compilerOptions = getCompilerOptionsForSourceFile(sourceFilePath);
|
|
74
|
+
if (!compilerOptions) return null;
|
|
75
|
+
const resolvedModule = ts.resolveModuleName(moduleSpecifier, sourceFilePath, compilerOptions, ts.sys).resolvedModule;
|
|
76
|
+
if (!resolvedModule) return null;
|
|
77
|
+
return isExistingFile(resolvedModule.resolvedFileName) ? resolvedModule.resolvedFileName : null;
|
|
78
|
+
};
|
|
79
|
+
const resolveImportPath = (sourceFilePath, moduleSpecifier) => moduleSpecifier.startsWith(".") ? resolveRelativeImportPath(sourceFilePath, moduleSpecifier) : resolveConfigImportPath(sourceFilePath, moduleSpecifier);
|
|
80
|
+
const getImportedSourceFile = (filePath) => {
|
|
81
|
+
const cached = importedSourceFileCache.get(filePath);
|
|
82
|
+
if (cached) return cached;
|
|
83
|
+
if (!fs.existsSync(filePath)) return null;
|
|
84
|
+
const sourceFile = importedSourceProject.createSourceFile(filePath, fs.readFileSync(filePath, "utf-8"), { overwrite: true });
|
|
85
|
+
importedSourceFileCache.set(filePath, sourceFile);
|
|
86
|
+
return sourceFile;
|
|
87
|
+
};
|
|
88
|
+
const extractImportedIdentifierValues = (node, visited) => {
|
|
89
|
+
if (!Node.isIdentifier(node)) return [];
|
|
90
|
+
const sourceFile = node.getSourceFile();
|
|
91
|
+
const sourceFilePath = sourceFile.getFilePath();
|
|
92
|
+
const importMatch = sourceFile.getImportDeclarations().find((importDecl) => importDecl.getNamedImports().some((namedImport) => (namedImport.getAliasNode()?.getText() ?? namedImport.getName()) === node.getText()));
|
|
93
|
+
if (!importMatch) return [];
|
|
94
|
+
const namedImport = importMatch.getNamedImports().find((candidate) => (candidate.getAliasNode()?.getText() ?? candidate.getName()) === node.getText());
|
|
95
|
+
if (!namedImport) return [];
|
|
96
|
+
const resolvedPath = resolveImportPath(sourceFilePath, importMatch.getModuleSpecifierValue());
|
|
97
|
+
if (!resolvedPath) return [];
|
|
98
|
+
const importedSourceFile = getImportedSourceFile(resolvedPath);
|
|
99
|
+
if (!importedSourceFile) return [];
|
|
100
|
+
const initializer = importedSourceFile.getVariableDeclaration(namedImport.getName())?.getInitializer();
|
|
101
|
+
return initializer ? extractStringLiterals(initializer, visited) : [];
|
|
102
|
+
};
|
|
6
103
|
/**
|
|
7
104
|
* Extracts string literal values from an expression.
|
|
8
105
|
*
|
|
@@ -108,7 +205,10 @@ const extractIdentifierValues = (node, visited) => {
|
|
|
108
205
|
}
|
|
109
206
|
return [];
|
|
110
207
|
});
|
|
111
|
-
|
|
208
|
+
if (values.length > 0) return values;
|
|
209
|
+
const importedValues = extractImportedIdentifierValues(node, visited);
|
|
210
|
+
if (importedValues.length > 0) return importedValues;
|
|
211
|
+
return extractLiteralValuesFromType(node);
|
|
112
212
|
};
|
|
113
213
|
/**
|
|
114
214
|
* Extract string literals from arrow functions or function expressions
|
|
@@ -7,7 +7,13 @@ let ts_morph = require("ts-morph");
|
|
|
7
7
|
/**
|
|
8
8
|
* Find all JSX usages of a component from its identifier
|
|
9
9
|
*/
|
|
10
|
-
const findJsxReferences = (identifier) =>
|
|
10
|
+
const findJsxReferences = (identifier) => {
|
|
11
|
+
try {
|
|
12
|
+
return identifier.findReferencesAsNodes().map((reference) => reference.getFirstAncestor((n) => ts_morph.Node.isJsxOpeningElement(n) || ts_morph.Node.isJsxSelfClosingElement(n))).filter((node) => Boolean(node) && (ts_morph.Node.isJsxOpeningElement(node) || ts_morph.Node.isJsxSelfClosingElement(node)));
|
|
13
|
+
} catch {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
};
|
|
11
17
|
|
|
12
18
|
//#endregion
|
|
13
19
|
exports.findJsxReferences = findJsxReferences;
|
|
@@ -6,7 +6,13 @@ import { Node, SyntaxKind } from "ts-morph";
|
|
|
6
6
|
/**
|
|
7
7
|
* Find all JSX usages of a component from its identifier
|
|
8
8
|
*/
|
|
9
|
-
const findJsxReferences = (identifier) =>
|
|
9
|
+
const findJsxReferences = (identifier) => {
|
|
10
|
+
try {
|
|
11
|
+
return identifier.findReferencesAsNodes().map((reference) => reference.getFirstAncestor((n) => Node.isJsxOpeningElement(n) || Node.isJsxSelfClosingElement(n))).filter((node) => Boolean(node) && (Node.isJsxOpeningElement(node) || Node.isJsxSelfClosingElement(node)));
|
|
12
|
+
} catch {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
};
|
|
10
16
|
|
|
11
17
|
//#endregion
|
|
12
18
|
export { findJsxReferences };
|
|
@@ -54,6 +54,10 @@ const resolveComponentInfo = (name) => {
|
|
|
54
54
|
const getModuleSpecifierValue = (importDecl) => {
|
|
55
55
|
return importDecl.getModuleSpecifierValue() ?? importDecl.getModuleSpecifier().getText().replace(/^['"]|['"]$/g, "");
|
|
56
56
|
};
|
|
57
|
+
const isTypeOnlyNamedImport = (importDecl, importName) => {
|
|
58
|
+
if (importDecl.isTypeOnly()) return true;
|
|
59
|
+
return importDecl.getNamedImports().find((namedImport) => namedImport.getName() === importName)?.isTypeOnly() ?? false;
|
|
60
|
+
};
|
|
57
61
|
const isUdsComponentModule = (moduleSpecifier) => {
|
|
58
62
|
const cleaned = moduleSpecifier.replace(/^['"]|['"]$/g, "");
|
|
59
63
|
return cleaned === "@yahoo/uds" || cleaned.startsWith("@yahoo/uds/");
|
|
@@ -122,7 +126,7 @@ const purgeFromCodeOptimized = async (code, options) => {
|
|
|
122
126
|
componentNameLookup = buildComponentNameLookup(componentData);
|
|
123
127
|
}
|
|
124
128
|
const startTime = performance.now();
|
|
125
|
-
const sourceFile = new ts_morph.Project({ useInMemoryFileSystem: true }).createSourceFile("input.tsx", code);
|
|
129
|
+
const sourceFile = new ts_morph.Project({ useInMemoryFileSystem: true }).createSourceFile(options.filePath ?? "input.tsx", code, { overwrite: true });
|
|
126
130
|
const stats = {
|
|
127
131
|
filesScanned: 1,
|
|
128
132
|
timeMs: 0,
|
|
@@ -132,7 +136,9 @@ const purgeFromCodeOptimized = async (code, options) => {
|
|
|
132
136
|
};
|
|
133
137
|
const imports = [];
|
|
134
138
|
sourceFile.getImportDeclarations().forEach((importDecl) => {
|
|
135
|
-
if (isUdsComponentModule(getModuleSpecifierValue(importDecl))) importDecl.getNamedImports().forEach((namedImport) =>
|
|
139
|
+
if (isUdsComponentModule(getModuleSpecifierValue(importDecl))) importDecl.getNamedImports().forEach((namedImport) => {
|
|
140
|
+
if (!namedImport.isTypeOnly() && !importDecl.isTypeOnly()) imports.push(namedImport.getName());
|
|
141
|
+
});
|
|
136
142
|
});
|
|
137
143
|
const componentProps = /* @__PURE__ */ new Map();
|
|
138
144
|
const referencedComponents = /* @__PURE__ */ new Set();
|
|
@@ -282,17 +288,16 @@ const findComponentReferences = (sourceFile, componentName) => {
|
|
|
282
288
|
sourceFile.getImportDeclarations().forEach((importDecl) => {
|
|
283
289
|
if (!isUdsComponentModule(getModuleSpecifierValue(importDecl))) return;
|
|
284
290
|
importDecl.getNamedImports().forEach((namedImport) => {
|
|
285
|
-
if (namedImport.getName()
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
291
|
+
if (namedImport.getName() !== componentName || isTypeOnlyNamedImport(importDecl, componentName)) return;
|
|
292
|
+
const localName = namedImport.getAliasNode()?.getText() ?? componentName;
|
|
293
|
+
require_jsx.findJsxReferences(namedImport.getFirstDescendantByKindOrThrow(ts_morph.ts.SyntaxKind.Identifier)).forEach((reference) => {
|
|
294
|
+
const key = `${reference.getTagNameNode().getText()}:${reference.getStart()}`;
|
|
295
|
+
if (!seenTags.has(key)) {
|
|
296
|
+
seenTags.add(key);
|
|
297
|
+
references.push(reference);
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
collectMatchingTags(localName);
|
|
296
301
|
});
|
|
297
302
|
});
|
|
298
303
|
return references;
|
|
@@ -53,6 +53,10 @@ const resolveComponentInfo = (name) => {
|
|
|
53
53
|
const getModuleSpecifierValue = (importDecl) => {
|
|
54
54
|
return importDecl.getModuleSpecifierValue() ?? importDecl.getModuleSpecifier().getText().replace(/^['"]|['"]$/g, "");
|
|
55
55
|
};
|
|
56
|
+
const isTypeOnlyNamedImport = (importDecl, importName) => {
|
|
57
|
+
if (importDecl.isTypeOnly()) return true;
|
|
58
|
+
return importDecl.getNamedImports().find((namedImport) => namedImport.getName() === importName)?.isTypeOnly() ?? false;
|
|
59
|
+
};
|
|
56
60
|
const isUdsComponentModule = (moduleSpecifier) => {
|
|
57
61
|
const cleaned = moduleSpecifier.replace(/^['"]|['"]$/g, "");
|
|
58
62
|
return cleaned === "@yahoo/uds" || cleaned.startsWith("@yahoo/uds/");
|
|
@@ -121,7 +125,7 @@ const purgeFromCodeOptimized = async (code, options) => {
|
|
|
121
125
|
componentNameLookup = buildComponentNameLookup(componentData);
|
|
122
126
|
}
|
|
123
127
|
const startTime = performance.now();
|
|
124
|
-
const sourceFile = new Project({ useInMemoryFileSystem: true }).createSourceFile("input.tsx", code);
|
|
128
|
+
const sourceFile = new Project({ useInMemoryFileSystem: true }).createSourceFile(options.filePath ?? "input.tsx", code, { overwrite: true });
|
|
125
129
|
const stats = {
|
|
126
130
|
filesScanned: 1,
|
|
127
131
|
timeMs: 0,
|
|
@@ -131,7 +135,9 @@ const purgeFromCodeOptimized = async (code, options) => {
|
|
|
131
135
|
};
|
|
132
136
|
const imports = [];
|
|
133
137
|
sourceFile.getImportDeclarations().forEach((importDecl) => {
|
|
134
|
-
if (isUdsComponentModule(getModuleSpecifierValue(importDecl))) importDecl.getNamedImports().forEach((namedImport) =>
|
|
138
|
+
if (isUdsComponentModule(getModuleSpecifierValue(importDecl))) importDecl.getNamedImports().forEach((namedImport) => {
|
|
139
|
+
if (!namedImport.isTypeOnly() && !importDecl.isTypeOnly()) imports.push(namedImport.getName());
|
|
140
|
+
});
|
|
135
141
|
});
|
|
136
142
|
const componentProps = /* @__PURE__ */ new Map();
|
|
137
143
|
const referencedComponents = /* @__PURE__ */ new Set();
|
|
@@ -281,17 +287,16 @@ const findComponentReferences = (sourceFile, componentName) => {
|
|
|
281
287
|
sourceFile.getImportDeclarations().forEach((importDecl) => {
|
|
282
288
|
if (!isUdsComponentModule(getModuleSpecifierValue(importDecl))) return;
|
|
283
289
|
importDecl.getNamedImports().forEach((namedImport) => {
|
|
284
|
-
if (namedImport.getName()
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
290
|
+
if (namedImport.getName() !== componentName || isTypeOnlyNamedImport(importDecl, componentName)) return;
|
|
291
|
+
const localName = namedImport.getAliasNode()?.getText() ?? componentName;
|
|
292
|
+
findJsxReferences(namedImport.getFirstDescendantByKindOrThrow(ts.SyntaxKind.Identifier)).forEach((reference) => {
|
|
293
|
+
const key = `${reference.getTagNameNode().getText()}:${reference.getStart()}`;
|
|
294
|
+
if (!seenTags.has(key)) {
|
|
295
|
+
seenTags.add(key);
|
|
296
|
+
references.push(reference);
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
collectMatchingTags(localName);
|
|
295
300
|
});
|
|
296
301
|
});
|
|
297
302
|
return references;
|
|
@@ -20,6 +20,7 @@ let knownComponents = null;
|
|
|
20
20
|
*/
|
|
21
21
|
let componentPaths = null;
|
|
22
22
|
let scannedComponentsDir = null;
|
|
23
|
+
const hasImportQuery = (moduleSpecifier) => moduleSpecifier.includes("?");
|
|
23
24
|
const scanComponentFilePaths = async (componentsDir) => (0, fast_glob.default)(require_entryPoints.getAllowedEntryFileGlobPatterns(), {
|
|
24
25
|
cwd: componentsDir,
|
|
25
26
|
absolute: true
|
|
@@ -474,7 +475,7 @@ const resolveImportedIdentifier = (identifier) => {
|
|
|
474
475
|
if (resolvedImport) return resolvedImport;
|
|
475
476
|
if (!importDecl.getNamedImports().find((n) => n.getName() === name)) return;
|
|
476
477
|
const moduleSpec = importDecl.getModuleSpecifierValue();
|
|
477
|
-
if (!moduleSpec.startsWith(".")) return;
|
|
478
|
+
if (!moduleSpec.startsWith(".") || hasImportQuery(moduleSpec)) return;
|
|
478
479
|
const resolvedBase = node_path.default.resolve(baseDir, moduleSpec);
|
|
479
480
|
return [
|
|
480
481
|
resolvedBase,
|
|
@@ -17,6 +17,7 @@ let knownComponents = null;
|
|
|
17
17
|
*/
|
|
18
18
|
let componentPaths = null;
|
|
19
19
|
let scannedComponentsDir = null;
|
|
20
|
+
const hasImportQuery = (moduleSpecifier) => moduleSpecifier.includes("?");
|
|
20
21
|
const scanComponentFilePaths = async (componentsDir) => fg(getAllowedEntryFileGlobPatterns(), {
|
|
21
22
|
cwd: componentsDir,
|
|
22
23
|
absolute: true
|
|
@@ -471,7 +472,7 @@ const resolveImportedIdentifier = (identifier) => {
|
|
|
471
472
|
if (resolvedImport) return resolvedImport;
|
|
472
473
|
if (!importDecl.getNamedImports().find((n) => n.getName() === name)) return;
|
|
473
474
|
const moduleSpec = importDecl.getModuleSpecifierValue();
|
|
474
|
-
if (!moduleSpec.startsWith(".")) return;
|
|
475
|
+
if (!moduleSpec.startsWith(".") || hasImportQuery(moduleSpec)) return;
|
|
475
476
|
const resolvedBase = path.resolve(baseDir, moduleSpec);
|
|
476
477
|
return [
|
|
477
478
|
resolvedBase,
|