Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Babel next plumbing #217

Merged
merged 38 commits into from
Aug 12, 2020
Merged

Babel next plumbing #217

merged 38 commits into from
Aug 12, 2020

Conversation

itsdouges
Copy link
Collaborator

@itsdouges itsdouges commented Jun 11, 2020

Ok confirmed we're going with a Babel plugin. We need to get this PR into a shape we're happy to merge and then we'll start working on features in styled components API.

@itsdouges itsdouges added the wip 🚧 Work in progress - don't judge too harshly. label Jun 11, 2020
@itsdouges itsdouges mentioned this pull request Jun 24, 2020
@itsdouges itsdouges force-pushed the babel-next branch 2 times, most recently from cb37215 to 90abb4a Compare June 28, 2020 03:50
@itsdouges itsdouges changed the title [WIP] Babel next Babel next plumbing Aug 2, 2020
@itsdouges itsdouges added new feature 🆕 New feature or request and removed wip 🚧 Work in progress - don't judge too harshly. labels Aug 2, 2020

visitStyledPath(path, state);
},
JSXOpeningElement(path, state) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Madou: Does spread operator works here 🤔? Something like this:

import '@compiled/css-in-js';

const props = {
  css: 'font-size:12px;'
}

const MyDiv = () => {
  return <div {...props}>hello</div>
};

Copy link
Contributor

@pgmanutd pgmanutd Aug 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't find JSXSpreadAttribute anywhere 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi - yeah currently that isn't supported. i don't see that as a very common use case. do you think it's useful to add it in?

my thoughts: do the bare minimum and then add more if it has wide spread usage.

needing a static css prop directly on the jsx element seems like the right path for me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah!! not that much important for css prop tbh. But yups for other props we should definitely consider it.

my thoughts: do the bare minimum and then add more if it has wide spread usage.

^^ I am sold 😛

if (t.isIdentifier(expression) && state.declarations) {
const declaration = state.declarations[expression.name];
if (t.isVariableDeclaration(declaration) && declaration.kind === 'const') {
// We only want to pick out variable declarations that are constants
Copy link

@jacklorusso jacklorusso Aug 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be an obvious answer - but why? :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets add some more context around why we are doing this.

path.node.specifiers = path.node.specifiers
.filter(
(specifier) =>
specifier.local.name !== 'styled' && specifier.local.name !== 'ClassNames'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay so no matter what import you use (i.e. what flavour of CSS-in-JS you like) we are going to filter out that import and replace it with CC and CS

@@ -0,0 +1,164 @@
import * as t from '@babel/types';
import kebabCase from '@compiled/ts-transform-css-in-js/dist/utils/kebab-case';
import { addUnitIfNeeded } from '@compiled/ts-transform-css-in-js/dist/utils/css-property';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these utils in the ast and css builders coming from the TS Transform package feels like an interesting package boundary to me. I guess it's an implementation detail that doesn't impact users at all so it doesn't matter too much, it's only a dev dependency so it doesn't really matter if installing the babel plugin also installs the TS transformer.

@itsdouges
Copy link
Collaborator Author

itsdouges commented Aug 10, 2020 via email

return;
}

const declarationName = path.node.declarations[0].id.name;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add comment explaining why we are doing this and potential pitfalls of the current implementation (name clashes)

const key = prop.key.name || prop.key.value;
let value = '';

if (t.isStringLiteral(propValue)) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets add comments with example code for each block to help visualize whats happening

return value;
};

const extractObjectExpression = (node: t.ObjectExpression, state: State): CSSOutput => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add jsdoc comments to each method explaining what its responsibility is for


node.properties.forEach((prop) => {
if (t.isObjectProperty(prop)) {
// Don't use prop.value directly as it extracts constants from identifiers if needed.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make this comment better

// eslint-disable-next-line @typescript-eslint/no-use-before-define
const result = extractTemplateLiteral(propValue, state);
value = result.css;
variables = variables.concat(result.variables);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets add a comment saying why we arent treating this like a mixin

variables.push({ name: variableName, expression: propValue });
value = `var(${variableName})`;
} else {
throw new Error(`Not supported.`);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change this to use a stack frame error (maybe in next PR)

variables = variables.concat(result.variables);
return;
} else {
throw new Error(`Declaration for ${prop.argument.name} could not be found.`);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see if we can throw stack frame error (in next PR)

return extractObjectExpression(node, state);
}

throw new Error('Unsupported node.');
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throw stack frame error (in another PR)

Copy link

@jacklorusso jacklorusso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Epic work so far with a few improvements on the way 👍

@itsdouges itsdouges merged commit 24ab686 into master Aug 12, 2020
@itsdouges itsdouges deleted the babel-next branch August 12, 2020 02:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature 🆕 New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants