-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Add support for styled-components syntax highlighting #1714
Conversation
[styled-components](https://github.com/styled-components/styled-components) is a widely used CSS-in-JS library. It lets users write their CSS in JavaScript as CSS strings. For example: ``` const Button = styled.button` color: blue; background: red; ` ``` This PR adds support for highlighting the styled-components template strings as CSS. We have been running this exact code [on the styled-components website for almost two years](https://github.com/styled-components/styled-components-website/blob/bbfcb0d21aaec9e8202609a67e7bba5278042056/utils/prismTemplateString.js) and it has worked perfectly. I have added tests for the feature and am willing to maintain this going forward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for contributing!
But before we can merge this, there are multiple issue we'll have to address.
- Dependencies:
How should this behave if the CSS language is not present?
I think the new token should not be added to JS if CSS is not present, so we just need to add a peer dependency to CSS incomponents.json
. - Style:
We ident using tabs and use single quotes for token names. - Redundancy:
The new token is basically a modified copy oftemplate-string
. My problem is that this increases redundancy and makes the language harder to maintain. - Correctness:
I don't really get why you modified thestring
regex. It just causes semi-colons and dollar signs to not be highlighted which is a problem if these characters appear in comments or strings (or after every CSS property...).
I get that white semi-colons look better on your website (examples) but it's simply not right to strangely cut CSS code into pieces IMO.
Also, there can be any number of spaces between tag and template string. - Please run gulp to create the minified files (and
components.js
).
My solution for number 3 and 4 would be this:
/**
* Creates a new pattern to match a template string with a special tag.
*
* @param {string} language The language inside the template string.
* @param {string} tag The regex pattern to match the tag.
* @returns {object} The new token.
* @example
* createTemplate('css', /\bcss/.source);
* createTemplate(); // template strings without tags
*/
function createTemplate(language, tag) {
var string = !language ? /[\s\S]+/ : {
pattern: /[\s\S]+/,
alias: 'language-' + language,
inside: Prism.languages[language]
};
return {
pattern: RegExp((tag ? '((?:' + tag + ')\\s*)' : '') + /`(?:\\[\s\S]|\${[^}]+}|[^\\`])*`/.source),
lookbehind: !!tag,
greedy: true,
inside: {
'interpolation': {
pattern: /\${[^}]+}/,
inside: {
'interpolation-punctuation': {
pattern: /^\${|}$/,
alias: 'punctuation'
},
rest: Prism.languages.javascript
}
},
'string': string
}
}
}
This will also allow us to easily add new tagged template strings in the future (like e.g. Polymer's html
; not that this should be part of this PR).
Thank you so much for that in-depth review! The latest commits clean everything up apart from 3. and 4.—I'm not entirely sure where to put that util and how to use it. Would you mind quickly implementing that? You'd be much faster than me 👍 |
Actually, this does not correctly highlight CSS, right? 🤔 |
What does? |
I mean, the CSS part inside the tagged template strings is not highlighted as CSS: styled.button`
color: blue;
` It is treated as a string, rather than as CSS. At least in the tests? |
Well, you did remove the CSS part. so that's to be expected. |
Oh yeah sorry, I totally messed that up 😅 Thank you! 🙏 |
Added `createTemplate`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
From my point of view, this is ready to merge.
But reviewing my own code... 😅
So I would like @mAAdhaTTah to have the final word on this.
Sorry for the dlay. Besides the conflicts we now have, this feels like it might be better as a Thoughts? |
@mAAdhaTTah if anything, it should be part of JSX since it is React-specific. What would you think about that? Happy to resolve the conflicts tomorrow if we can agree on moving this to JSX! |
@mxstbr |
Moving this to JS-Extras also means that the if (Prism.languages.css) {
Prism.languages.javascript['template-string'].unshift(createTemplate('css', /\b(?:styled(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))*)*|css|createGlobalStyle|keyframes)/.source));
} Technically, I also think that this feature should be moved of JS-Extras. All three lines of it... |
Also, JS-Extras has its dependencies set up in a way so that it doesn't affect TypeScript.
It might seem like overkill, but I think that option 2 is the best one. |
@mAAdhaTTah Regarding offloading the CSS templates: |
Ah, just opened a new issue which is a superset of this (#1930 - for handling all languages tagged template literals) and didn't see this while searching for similar issues. I will mention this in the other issue. This could also be a good starting point for the other languages (and also for other CSS-in-JS libs like |
I would vote to add the eventual change with all languages as part of the main default JS language, since tagged template strings with different languages are common in places other than React / JSX / other frameworks. |
I'll close this now as all of the changes in this were also part of #1931. |
styled-components is a widely used CSS-in-JS library. It lets users write their CSS in JavaScript as CSS strings. For example:
This PR adds support for highlighting the styled-components template strings as CSS.
We have been running this exact code on the styled-components website for almost two years and it has worked perfectly.
I have added tests for the feature and am willing to maintain this going forward.
/cc @kitten @probablyup the other core maintainers of the styled-components package