Thom1729 / Sublime-JS-Custom

Customizable JavaScript syntax highlighting for Sublime Text.
MIT License
137 stars 9 forks source link

Improvement for styled-components / emotion #93

Closed kud closed 3 years ago

kud commented 4 years ago

Hello Thom!

I've got some issues with css-in-js. See this picture:

image

Variables aren't coloured. Neither some nested styles.

Can I help in any way?

Thank you!

wbond commented 4 years ago

You probably already know this, but from what I can tell the styled components use the file Styled Components.tmLanguage instead of scope:source.css#rule-list-body or something like that. It seems the styled components syntax is rather out-of-date.

Thom1729 commented 4 years ago

Yeah, I'm using the Styled Components syntax from the babel-sublime package specifically to provide a migration path for those users. I should probably update it to a more modern syntax if one exists and/or allow you to specify a custom Styled Components syntax definition in the JS Custom configuration.

tsujp commented 4 years ago

In addition to this I've noticed that if you pass props to a styled component, or types, it breaks the syntax highlighting. See images below, the only difference is me removing the type <IProps>.

broken with type

working without type

Thom1729 commented 4 years ago

The <IProps> thing will be addressed sooner or later as part of the TypeScript extension.

I sat down today to change the Styled Components extension so that you can specify your own third-party syntax for it, but I actually couldn't find a standalone Styled Components syntax. The only ones I found were from babel-sublime (used here) and Naomi. The structure of Naomi is a bit esoteric, so I'll have to take a look at whether I could make use of it.

Barring that, I suppose I'd have to improve it myself. I don't use Styled Components and have no immediate plans to, so I'd be effectively starting from scratch, and long-term maintenance might be a concern. Are the contents of the template string just a list of CSS rules, or is there extra syntax? Maybe I could get away with simply referring to a context in the core CSS syntax definition rather than a separate Styled Components syntax definition..

tsujp commented 4 years ago

I'd have to double check but as a starting point you can put SCSS type styles and in addition to that JS/TS to extend functionality so it's a combination of both. Perhaps we could work on this together? I'd need guidance on how syntax highlighting etc works though as I have no idea but I am able and willing.

wbond commented 4 years ago

@tsujp Is it SCSS, or just CSS? If you haven't already, reading https://www.sublimetext.com/docs/syntax.html#ver-dev will be a good place to start.

kud commented 4 years ago

CSS-in-JS has nested declarations, and it's rather the same that SCSS.

const Component = styled.div`
  &:hover {
    background: yellow;
  }
`
wbond commented 4 years ago

Ah, then reusing the CSS syntax won't be super useful at this moment.

kud commented 4 years ago

A complex example:

Timeline.Item.Bullet = styled.div`
  background: white;
  padding: 0.3rem;
  border-radius: 50px;
  width: 4rem;
  height: 4rem;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;

  transition: width 150ms ease, margin 150ms ease;

  ${({ state }) =>
    state === "start" &&
    css`
      margin-top: 1.6rem;
      margin-bottom: -1.6rem;
      width: 1rem;
      height: 1rem;
      cursor: initial;

      ${Timeline.Item.Bullet.Element.TextBox} {
        top: 10px;
      }

      ${Timeline.Item.Bullet.Element.Text} {
        transform: translateX(-10%);
      }
    `}

    ${({ state }) =>
      state === "end" &&
      css`
        margin-top: 1.6rem;
        margin-bottom: -1.6rem;
        width: 1rem;
        height: 1rem;
        cursor: initial;

        ${Timeline.Item.Bullet.Element.TextBox} {
          top: 10px;
        }

        ${Timeline.Item.Bullet.Element.Text} {
          transform: translateX(-90%);
        }
      `}

  ${({ isSelected }) =>
    isSelected &&
    css`
      width: auto;
      min-width: 100px;
    `}

  ${({ isSelected, state }) =>
    !isSelected &&
    !state &&
    css`
      &:hover {
        width: 6rem;
        margin-left: -1rem;
        margin-right: -1rem;
      }
    `}
`
kud commented 4 years ago

This is the render with Naomi:

image

kud commented 4 years ago

and with VS Code:

image

wbond commented 4 years ago

It seems the styled components are immediately a rule list, but can also have custom selectors that don't exactly reflect CSS. From https://styled-components.com/docs/api#supported-css:

They have descendent selectors:

> p {
    text-decoration: underline;
}

Self-referential selectors:

&:hover {
    background: palevioletred;
}

Those can be combined with other selector chains:

html.test & {
    display: none;
}

But then media queries get thrown in:

@media (max-width: 600px) {
    background: tomato;
    &:hover {
        background: yellow;
    }
}

Of course there is the interpolated JS in there also.

My hunch is we can re-use the CSS rule-list-body, but then will have to do a little more work for the selectors since it supports a combination of custom selectors and &, plus media queries.

Thom1729 commented 3 years ago

@kud I've rewritten the Styled Components highlighting for the 4.1 beta. If you don't mind being on the bleeding edge, you can try that out and see if it works better for you. Feedback appreciated!

kud commented 3 years ago

Hello @Thom1729 I'm sorry I don't use ST anymore. But thanks for notifying me about this. I'll try it if I come back to ST. 😊

2Pacalypse- commented 3 years ago

When's the plan to release the 4.1? I would like to test this, but messing about with installing beta releases manually seems like too much work ^^.

Thom1729 commented 3 years ago

I'd expect 4.1 within the next week or two. There's at least one minor feature I think needs adding. (Also, there's a temporary issue with the Package Control listing that needs to be ironed out.)

Thom1729 commented 3 years ago

FYI, now that the PC issue is fixed, you can try out the beta by simply adding the following to your Package Control settings:

"install_prereleases":
[
    "JSCustom"
],
2Pacalypse- commented 3 years ago

I did that, but I didn't notice any difference, I think. Is there a way to easily see what's the current installed version and what specific styled-components changes would be most visible?

Thom1729 commented 3 years ago

This is how it should look in 4.0.6:

JS-Custom-Styled-Before

And in the beta:

JS-Custom-Styled-After
2Pacalypse- commented 3 years ago

Yep, seems to work great!

A couple of weird use cases that I found that don't get styled properly, but it's completely fine even if they don't to me:

image

image

And not sure if CSS variables should be styled differently, but it seems they aren't:

image

Thom1729 commented 3 years ago

Most of those look like bugs that can/should be fixed.

The second one — the template string inside the interpolation — is working as intended, and I don't think it would be practical or desirable to make have all template strings in interpolations follow their ‘parent’ template. However, the user could do something like configure custom_templates.comments to manually mark the inner template, e.g. /*styled*/`flex-grow: 1;`. At the moment, I don't think there's a good hook in the new Styled Components syntax definition for this, but I could add one.

2Pacalypse- commented 3 years ago

Yeah, I assumed the second one is working as intended.

However, the user could do something like configure custom_templates.comments to manually mark the inner template, e.g. /styled/flex-grow: 1; . At the moment, I don't think there's a good hook in the new Styled Components syntax definition for this, but I could add one.

Eh, I wouldn't bother tbh. I'd feel pretty uneasy committing code that has some cryptic comments that are used to configure a particular text editor. Also, styled-components do have a css helper function which could be used here. And voila, you get perfect styling!

image

Thom1729 commented 3 years ago

Closing since the original issues should be fixed by now. Feel free to open new issues for any remaining bugs/missing features.