Skip to content

Instantly share code, notes, and snippets.

@jquense
Created August 30, 2018 15:04
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jquense/c2a92f1c909552f295bb7953fcd2ce4d to your computer and use it in GitHub Desktop.
Save jquense/c2a92f1c909552f295bb7953fcd2ce4d to your computer and use it in GitHub Desktop.
const { utils } = require('react-docgen');
const { default: resolveHOC } = require('react-docgen/dist/utils/resolveHOC');
const {
default: resolveToModule,
} = require('react-docgen/dist/utils/resolveToModule');
module.exports = ({ moduleName = 'styled-components' } = {}) => {
const isStyledExpression = (tagPath, t) =>
(t.CallExpression.check(tagPath.node) &&
tagPath.get('callee').node.name === 'styled') ||
(t.MemberExpression.check(tagPath.node) &&
tagPath.get('object').node.name === 'styled');
function isStyledComponent(def, t) {
if (
!t.TaggedTemplateExpression.check(def.node) ||
!isStyledExpression(def.get('tag'), t)
) {
return false;
}
const module = resolveToModule(def.get('tag'));
return !!module && module === moduleName;
}
const exportTagged = (path, t) => {
const definitions = utils.resolveExportDeclaration(path, t);
const components = [];
definitions.filter(Boolean).forEach(def => {
let comp = def;
if (isStyledComponent(comp, t)) {
components.push(comp);
} else {
comp = utils.resolveToValue(resolveHOC(comp));
if (isStyledComponent(comp, t)) components.push(comp);
}
});
return components;
};
function findExportedStyledComponent(ast, recast) {
const components = [];
const t = recast.types.namedTypes;
const visitor = path => {
components.push(...exportTagged(path, t));
return false;
};
recast.visit(ast, {
visitFunctionDeclaration: false,
visitFunctionExpression: false,
visitClassDeclaration: false,
visitClassExpression: false,
visitIfStatement: false,
visitWithStatement: false,
visitSwitchStatement: false,
visitCatchCause: false,
visitWhileStatement: false,
visitDoWhileStatement: false,
visitForStatement: false,
visitForInStatement: false,
visitExportDefaultDeclaration: visitor,
});
return components;
}
function findAllExportedStyledComponents(ast, recast) {
const components = [];
const t = recast.types.namedTypes;
const visitor = path => {
components.push(...exportTagged(path, t));
return false;
};
recast.visit(ast, {
visitFunctionDeclaration: false,
visitFunctionExpression: false,
visitClassDeclaration: false,
visitClassExpression: false,
visitIfStatement: false,
visitWithStatement: false,
visitSwitchStatement: false,
visitCatchCause: false,
visitWhileStatement: false,
visitDoWhileStatement: false,
visitForStatement: false,
visitForInStatement: false,
visitExportDeclaration: visitor,
visitExportNamedDeclaration: visitor,
visitExportDefaultDeclaration: visitor,
});
return components;
}
function findAllStyledComponents(ast, recast) {
const components = [];
const t = recast.types.namedTypes;
recast.visit(ast, {
visitFunctionDeclaration: false,
visitFunctionExpression: false,
visitClassDeclaration: false,
visitClassExpression: false,
visitIfStatement: false,
visitWithStatement: false,
visitSwitchStatement: false,
visitCatchCause: false,
visitWhileStatement: false,
visitDoWhileStatement: false,
visitForStatement: false,
visitForInStatement: false,
visitTaggedTemplateExpression(path) {
let comp = path;
if (isStyledComponent(path, t)) {
components.push(path);
} else {
comp = utils.resolveToValue(resolveHOC(path));
if (isStyledComponent(comp, t)) components.push(comp);
}
return false;
},
});
return components;
}
return {
findAllStyledComponents,
findAllExportedStyledComponents,
findExportedStyledComponent,
};
};
@dreyks
Copy link

dreyks commented Oct 24, 2019

hey! any plans to bring this to astroturf as well? or maybe at least publish as a package

@jquense
Copy link
Author

jquense commented Oct 24, 2019

yes! I'm working on a documentation gatsby theme, that contains this, as well as a bunch of other of these sort of things i rewrite all the time for docs sites. They will be published individually as npm packages

@dreyks
Copy link

dreyks commented Oct 24, 2019

great! thx. I'll vendor a local version for now.

Also if you need any help with all this I might have some spare time

@jquense
Copy link
Author

jquense commented Oct 24, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment