Sitelet https://github.com/primer/github-vscode-theme/pull/4
Skip to content

Introduce light+dark theme via use of @primer/primitives - #4

Merged
simurai merged 9 commits into
primer:masterfrom
paramaggarwal:master
Apr 27, 2020
Merged

simurai merged 9 commits into
primer:masterfrom
paramaggarwal:master

Conversation

@paramaggarwal

@paramaggarwal paramaggarwal commented Apr 23, 2020 •

Copy link
Copy Markdown
Contributor
  • Automatic dark theme generation - works beautifully!
  • Imported color values rather than hard-coded values.
  • More readable values like colors.red[3].

Pending:

  • Values that do not use Primer Colors are not inverting correctly. This is a great reason now to enforce use of Primer colors everywhere.

Light

Screenshot 2020-04-23 at 9 38 25 PM

Dark

Screenshot 2020-04-23 at 9 38 29 PM

System

Apr-23-2020 22-32-58

(fixes #3)

@paramaggarwal paramaggarwal left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added some comments to explain the thought process/plan.

Comment thread themes/light.json
"foreground": "#444d56",
"descriptionForeground": "#6a737d",
"errorForeground": "#cb2431",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The reason these lines got removed is because this file is now auto-generated. I have intentionally not modified any theme config/colors as I wanted this PR to purely focus on auto-generation first.

Comment thread src/index.js Outdated
} else if (name === "white") {
darkColors.black = val;
} else {
darkColors[name] = [...val].reverse();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is the key part. The colors array go from light to dark shades. For the dark theme, we simply reverse the ordering. This works surprisingly well!

Comment thread src/index.js
const fs = require("fs");
const { colors } = require("@primer/primitives");

const getTheme = require("./theme");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The theme shall reside in this one single place and it references the Primer primitives rather than hardcoding any colors.

Comment thread package.json
"@primer/primitives": "^2.0.1"
},
"scripts": {
"build": "node src/index.js"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The script to auto-generate the two themes. This can be hooked into a prepublish step.

Comment thread package.json Outdated
"publisherId": "7c1c19cd-78eb-4dfb-8999-99caf7679002"
},
"devDependencies": {
"@primer/primitives": "^2.0.1"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The source of our raw color values.

Comment thread src/theme.js Outdated
return {
name: name,
colors: {
focusBorder: colors.blue[4],

@paramaggarwal paramaggarwal Apr 23, 2020 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I had written a script to reverse-engineer the color reference from the underlying hardcoded hex string. Also, I have verified that the output theme config is exactly the same as before.

@paramaggarwal

paramaggarwal commented Apr 23, 2020 •

Copy link
Copy Markdown
Contributor Author

There are total 20 color values that do not have a direct mapping to the colors in Primer Primitives. I have started compiling a few of the suggested mappings:

  • button.background: #159739 -> #34d058 from colors.green[4]
  • button.hoverBackground: #138934 -> #22863a from colors.green[6]
  • list.hoverBackground: #ebf0f4 -> #dbedff from colors.blue[1]
  • list.inactiveSelectionBackground: #e8eaed -> #fafbfc from colors.gray[0]
  • list.activeSelectionBackground: #e2e5e9 -> #c8e1ff from colors.blue[2]
  • activityBar.activeBorder: #f9826c -> #fdaeb7 from colors.red[2]
  • tab.activeBorderTop: #f9826c -> #fdaeb7 from colors.red[2]

@simurai simurai removed the fr-skip label Apr 24, 2020

@simurai simurai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is awesome.. 😻 ❤️ Also thanks for explaining everything. 🙇

There are total 20 color values that do not have a direct mapping to the colors in Primer Primitives.

Yeah, some are custom colors that we started to use in https://github.com/primer/css but aren't part of the "system" yet.

we might need the color npm module to make some slight darken(), lighten() operations on the raw color values.

Sometimes no color from the scale made sense. Like when hovering, it should only change a tiny bit but not as much as the next number in the scale. Having color functions would be nice. 👍

we simply reverse the ordering. This works surprisingly well!

Indeed it does. Although I wonder if hand tweaking the colors, here and there, could improve it even more? 🤔 Would something like the following be possible?

  • If only one color defined: scope: colors.blue[4], -> inverse for dark
  • If 2 colors defined: scope: { colors.blue[4], colors.blue[3] }, -> first is for light, second is for dark

That would allow to keep the scopes in sync, auto-inverse colors, but still be able to hand-tweak them if needed.

Comment thread package.json Outdated
Co-Authored-By: simurai <simulus@gmail.com>
@simurai

simurai commented Apr 24, 2020 •

Copy link
Copy Markdown
Contributor

btw. sorry, this PR now has a merge conflict since these 3 scopes got added.

Update: Should be fixed.

@paramaggarwal

Copy link
Copy Markdown
Contributor Author

I like all the suggestions.

  1. For the colors that don't exist directly in the color system, will use the lighten(), darken() approach. I could find the raw colors here.
  2. The ability to manually specify dark and light variants will be nice - will implement this.

@simurai

simurai commented Apr 27, 2020

Copy link
Copy Markdown
Contributor
  1. For the colors that don't exist directly in the color system, will use the lighten(), darken() approach. I could find the raw colors here.

No worries if converting the hex values into lighten()/darken() are hard to figure out. I just "randomly" tweaked them in Chrome's DevTools, so might not be easy to backwards-engineer them all the time. I can give it a try too. And it's also ok if they don't stay 100% the same. It's often just a "bit darker than the background".

@paramaggarwal

paramaggarwal commented Apr 27, 2020 •

Copy link
Copy Markdown
Contributor Author

✅ - ability to specify a manual mapping of colors pick({ light: XXX, dark: YYY }).
✅ - auto generate color by flipping luminance in HSL value for out-of-theme colors.
✅ - Added npm start to regenerate the theme files when a color value is modified.
✅ - Updated README with steps.

An approach that I found to create dark colors automatically is to use the HSL version and then flip the L value. If L is 10% in light, then the dark version will have 90%. This works well.

I am using this theme now and love it. One thing that I like about this PR is that it does not touch any original color value at all from light.json and the dark.json theme is completely auto-generated!

@simurai

simurai commented Apr 27, 2020 •

Copy link
Copy Markdown
Contributor

An approach that I found to create dark colors automatically is to use the HSL version and then flip the L value. If L is 10% in light, then the dark version will have 90%. This works well.

Nice! I guess with darken/lighten it's probably not needed that often since most of these colors are small variations. But still good to have as a fallback. 👍

One thing that I like about this PR is that it does not touch any original color value at all from light.json and the dark.json theme is completely auto-generated!

Yep, 0 regressions. 💥

Ok, I think this PR is good to merge. We can polish it more in follow-up PRs. Thanks for getting this up and running in no time. ❤️ 🙇

@simurai
simurai merged commit 5e2cb4a into primer:master Apr 27, 2020
@paramaggarwal

Copy link
Copy Markdown
Contributor Author

Thanks! 😊

@simurai

simurai commented May 8, 2020

Copy link
Copy Markdown
Contributor

...and published to the Marketplace. 🎉 /cc @paramaggarwal

@paramaggarwal

Copy link
Copy Markdown
Contributor Author

Wow! Great news @simurai!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Import colours from Primer Colors by name

3 participants