@dr.pogodin/babel-plugin-react-css-modules
Version:
Transforms styleName to className using compile time CSS module resolution.
73 lines • 3.91 kB
JavaScript
/* global console */
import optionsDefaults from "./schemas/optionsDefaults.js";
const isNamespacedStyleName = styleName => styleName.includes('.');
const handleError = (message, handleMissingStyleName) => {
if (handleMissingStyleName === 'throw') {
throw new Error(message);
} else if (handleMissingStyleName === 'warn') {
// eslint-disable-next-line no-console
console.warn(message);
}
return null;
};
const getClassNameForNamespacedStyleName = (styleName, styleModuleImportMap, handleMissingStyleNameOption) => {
// Note:
// Do not use the desctructing syntax with Babel.
// Desctructing adds _slicedToArray helper.
const styleNameParts = styleName.split('.');
const [importName, moduleName] = styleNameParts;
const handleMissingStyleName = handleMissingStyleNameOption || optionsDefaults.handleMissingStyleName;
if (!moduleName) {
return handleError(`Invalid style name: ${styleName}`, handleMissingStyleName);
}
if (!styleModuleImportMap[importName]) {
return handleError(`CSS module import does not exist: ${importName}`, handleMissingStyleName);
}
if (!styleModuleImportMap[importName][moduleName]) {
return handleError(`CSS module does not exist: ${moduleName}`, handleMissingStyleName);
}
return styleModuleImportMap[importName][moduleName];
};
const getClassNameFromMultipleImports = (styleName, styleModuleImportMap, handleMissingStyleNameOption) => {
const handleMissingStyleName = handleMissingStyleNameOption || optionsDefaults.handleMissingStyleName;
const importKeysWithMatches = Object.keys(styleModuleImportMap).map(importKey => styleModuleImportMap[importKey][styleName] && importKey).filter(importKey => importKey);
if (importKeysWithMatches.length > 1) {
throw new Error(`Cannot resolve styleName "${styleName}" because it is present in multiple imports:` + `\n\n\t${importKeysWithMatches.join('\n\t')}\n\nYou can resolve this by using a named import, e.g:` + `\n\n\timport foo from "${importKeysWithMatches[0]}";` + `\n\t<div styleName="foo.${styleName}" />` + '\n\n');
}
if (importKeysWithMatches.length === 0) {
return handleError(`Could not resolve the styleName '${styleName}'.`, handleMissingStyleName);
}
return styleModuleImportMap[importKeysWithMatches[0]][styleName];
};
export default (styleNameValue, styleModuleImportMap, options) => {
const styleModuleImportMapKeys = Object.keys(styleModuleImportMap);
const {
autoResolveMultipleImports = optionsDefaults.autoResolveMultipleImports,
handleMissingStyleName = optionsDefaults.handleMissingStyleName
} = options || {};
if (!styleNameValue) {
return '';
}
return styleNameValue.split(' ').filter(styleName => styleName).map(styleName => {
if (isNamespacedStyleName(styleName)) {
return getClassNameForNamespacedStyleName(styleName, styleModuleImportMap, handleMissingStyleName);
}
if (styleModuleImportMapKeys.length === 0) {
throw new Error(`Cannot use styleName attribute for style name '${styleName}' without importing at least one stylesheet.`);
}
if (styleModuleImportMapKeys.length > 1) {
if (!autoResolveMultipleImports) {
throw new Error(`Cannot use anonymous style name '${styleName}' with more than one stylesheet import without setting 'autoResolveMultipleImports' to true.`);
}
return getClassNameFromMultipleImports(styleName, styleModuleImportMap, handleMissingStyleName);
}
const styleModuleMap = styleModuleImportMap[styleModuleImportMapKeys[0]];
if (!styleModuleMap[styleName]) {
return handleError(`Could not resolve the styleName '${styleName}' in ${styleModuleImportMapKeys[0]}.`, handleMissingStyleName);
}
return styleModuleMap[styleName];
})
// Remove any styles which could not be found (if handleMissingStyleName === 'ignore')
.filter(className => className).join(' ');
};
//# sourceMappingURL=getClassName.js.map