UNPKG

@dr.pogodin/babel-plugin-react-css-modules

Version:

Transforms styleName to className using compile time CSS module resolution.

73 lines 3.91 kB
/* 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