jaywcjlove / svgtofont

Read a set of SVG icons and ouput a TTF/EOT/WOFF/WOFF2/SVG font.
https://jaywcjlove.github.io/svgtofont
MIT License
515 stars 81 forks source link

feat: css vars #203

Closed RobbyUitbeijerse closed 1 year ago

RobbyUitbeijerse commented 1 year ago

hey there!


We are in the middle of transitioning a codebase from scss to css variables. It gives us more flexibility over the existing scss variables and would allow us to move to solely PostCSS based compilation in the future, without the need for sass preprocessing.


In order to make it happen we would like to get rid of $icon-whatever; variables that are scattered throughout our codebase.

In order to make this happen, I did two notable things;

This leaves us with the following output depending on whenever you want to use the css vars over the existing options:

:root {
  --icon-adobe: "\ea01";
  --icon-demo: "\ea02";
  --icon-git: "\ea03";
  --icon-left: "\ea04";
  --icon-stylelint: "\ea05";
}

.icon-adobe:before { content: var(--icon-adobe); }
.icon-demo:before { content: var(--icon-demo); }
.icon-git:before { content: var(--icon-git); }
.icon-left:before { content: var(--icon-left); }
.icon-stylelint:before { content: var(--icon-stylelint); }

Please note I’ve made sure to not adjust any of the existing output. What I however did do is update the existing css example template in order to move to what I consider a better default for css: css variables and declarative usage of variables within the pseudo element.

Let me know what you think! Happy to adjust the solution

jaywcjlove commented 1 year ago

@RobbyUitbeijerse This is a very good idea. Is there a switch to enable new features.

RobbyUitbeijerse commented 1 year ago

Hey @jaywcjlove,

woops! I forgot to commit my compatibility solution.

I've now set it up in a way that's compatible with all the existing options. So the output depends on the template people would use for the template.css file. For example:

this would lead to existing output, ensuring that nothing would break:

_{{filename}}.css.template

{{cssString}}

However, if you update the template like this, you would get the new output:

_{{filename}}.css.template

:root {
  {{cssRootVars}}
}

{{cssVars}}

The 'switch' here, is that you can use existing variable: {{ cssString }} , and nothing would change for any existing user. While if you use {{ cssRootVars }} and {{ cssVars }}, the person would get the new, more 'modern' output.

This means that:

Let me know what you think!

jaywcjlove commented 1 year ago

@RobbyUitbeijerse You can add a useCSSVal to control whether to use css variables. All the content in js can be spliced and passed to {{cssString}}

jaywcjlove commented 1 year ago

pnpm-lock.yaml file can be added to .gitignore to ignore commits, I don't really like using pnpm @RobbyUitbeijerse

RobbyUitbeijerse commented 1 year ago

@jaywcjlove hey! cleaned it up a little. cssString now outputs both the existing output as well based on the option. I did however keep the cssRootVars. Also removed that stray pnpm lockfile

would you prefer me to merge it all together, both the :root {} stuff as well as the class output?

jaywcjlove commented 1 year ago

@RobbyUitbeijerse Yes, I think the :root {} string is also included in cssString, In this way, the template is as simple as possible and placed in the js logic.

- :root {
-  {{cssRootVars}}
- }
{{cssString}}
RobbyUitbeijerse commented 1 year ago

hey there @jaywcjlove , I think I've got it covered.

I figured it out by keeping track of two variables internally: cssString and cssRootVars.

Based on the index of the unicodeObject loop, I add the opening and closing tags for the :root {} selector in cssRootVars.

if (options.useCSSVars) {
  if (index === 0) cssRootVars.push(`:root {\n`)
  cssRootVars.push(`--${symbolName}: "\\${encodedCodes.toString(16)}";\n`);
  cssString.push(`.${symbolName}:before { content: var(--${symbolName}); }\n`);
  if (index === self.length - 1) cssRootVars.push(`}\n`)
} else {
  cssString.push(`.${symbolName}:before { content: "\\${encodedCodes.toString(16)}"; }\n`);
}

Once both arrays are filled with the variable formats I concat them together based on the options.useCSSVars

if (options.useCSSVars) {
  cssString = [...cssRootVars, ...cssString]
}

it feels a bit hacky, but through this method we have a complete cssString based on options.UseCSSVars without restructuring the script. I have some ideas for cleaning up the entire script, but I would like to keep it outside of the scope of the current PR.

Let me know what you think. I squashed the different commits into one to not pollute the git history.

jaywcjlove commented 1 year ago

@RobbyUitbeijerse 👍