Description
It'd be awesome if new-component
could include base styling.
There are two issues here: Coming up with the individual templates for each style solution, as well as the underlying architecture changes to make this possible.
Templates by style solution
styled-components
For styled-components
, I spoke with Max on twitter and we think the best solution would be to update the template to be something like this:
// Whatever.js
import React, { Component } from 'react';
import styled from 'styled-components';
class Whatever extends Component {
render() {
return <Wrapper />;
}
}
const Wrapper = styled.div`
`;
export default Whatever;
A near-identical template could be used for emotion
(literally just swapping out styled-components
for emotion/react
, in the import line.
CSS modules
For CSS modules, the JS template would need to be updated to something like this:
// Whatever.js
import React, { Component } from 'react';
import styles from './Whatever.css';
class Whatever extends Component {
render() {
return <div className={styles.wrapper} />;
}
}
export default Whatever;
We'd also need the CSS file, but it can be super minimal:
// Whatever.css
.wrapper {
}
Aphrodite
Finally, given that I work at KA, I'd like to add Aphrodite support! it would look like something of a mix of these earlier two solutions (all defined in the JS file, but using className
and a styles
object)
Architecture Changes
It actually seems like a pretty hard problem, figuring out how to add these new templates in a sustainable way. Because we support 3 different kinds of components (class, pure, functional), ideally I don't want to have to create 3 * 4 templates, for each possible permutation.
Thinking off the top of my head... One idea is to split the template into "quadrants", little mix-and-match pieces. You'd assemble the final template by picking the pieces you need, based on the type of component and style solution.
I imagine the different "areas" are:
- React imports
- Style imports
- component definition
- component render contents
- below-component footer (for stuff like
const Wrapper = styled.div
) - exports (
export default Whatever
)
Here's a very rough first pass (this could be all wrong, just going with an idea :) )
// templates/react-imports.js
export default {
functional: "import React from 'react';"
class: "import React, { Component } from 'react';"
};
// templates/style-imports.js
export default {
'styled-components': "import styled from 'styled-components';",
};
// templates/render-contents.js
export default {
'styled-components': "<Wrapper />",
};
// templates/component-definition.js
// NOTE: This one is a bit tricky, since the `render-contents` are within it.
// Maybe something like this?
export default {
// NOTE: ignore the spaces between ` ` `. Just not sure how to escape in markdown.
functional = (ComponentName, renderContents) => ` ` `
const ${ComponentName} = (
return ${renderContents}
);
` ` `
}
And then you'd just combine them to create the actual template:
import reactImportTemplates from './templates/react-imports';
import styleImportTemplates from './templates/style-imports';
import renderContentTemplates from './templates/render-contents';
import componentDefinitionTemplates from './templates/component-definition';
// Pretend these vars are defined from program input args
const componentName = 'Whatever';
const componentType = 'class';
const style = 'styled-components';
const renderContents = renderContentTemplates[style];
return ` ` `
${reactImportTemplates[componentType]}
${styleImportTemplates[style]}
${componentDefinitionTemplate[componentType](componentName, renderContents)}
` ` `;
This is of course a very rough draft, haven't thought through all the implications. Happy to discuss!
Going forward, I don't anticipate having that much time to spend on this (currently deeply involved in another side project, + my day job), so if anyone wanted to take this on, that'd be awesome. I want this to be a community project! Otherwise, I'll do my best to get to this in the next month or two :)