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

feat: add custom variables to utility classes #2022

Merged
merged 9 commits into from
Apr 26, 2023

Conversation

andrey-canon
Copy link

Description

Use ccs variables in utility-classes.css instead of resolved values.

Issue #2016

Deploy Preview

Include a direct link to your changes in this PR's deploy preview here (e.g., a specific component page).

Merge Checklist

  • If your update includes visual changes, have they been reviewed by a designer? Send them a link to the Netlify deploy preview, if applicable.
  • Does your change adhere to the documented style conventions?
  • Do any prop types have missing descriptions in the Props API tables in the documentation site (check deploy preview)?
  • Were your changes tested using all available themes (see theme switcher in the header of the deploy preview, under the "Settings" icon)?
  • Were your changes tested in the example app?
  • Is there adequate test coverage for your changes?
  • Consider whether this change needs to reviewed/QA'ed for accessibility (a11y). If so, please add wittjeff and adamstankiewicz as reviewers on this PR.

Post-merge Checklist

  • Verify your changes were released to NPM at the expected version.
  • If you'd like, share your contribution in #show-and-tell.
  • 🎉 🙌 Celebrate! Thanks for your contribution.

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Feb 14, 2023
@openedx-webhooks
Copy link

Thanks for the pull request, @andrey-canon! Please note that it may take us up to several weeks or months to complete a review and merge your PR.

Feel free to add as much of the following information to the ticket as you can:

  • supporting documentation
  • Open edX discussion forum threads
  • timeline information ("this must be merged by XX date", and why that is)
  • partner information ("this is a course on edx.org")
  • any other information that can help Product understand the context for the PR

All technical communication about the code itself will be done via the GitHub pull request interface. As a reminder, our process documentation is here.

Please let us know once your PR is ready for our review and all tests are green.

@andrey-canon
Copy link
Author

@adamstankiewicz

@codecov
Copy link

codecov bot commented Feb 14, 2023

Codecov Report

Patch and project coverage have no change.

Comparison is base (387e3c4) 90.94% compared to head (aac2cea) 90.94%.

Additional details and impacted files
@@           Coverage Diff           @@
##            alpha    #2022   +/-   ##
=======================================
  Coverage   90.94%   90.94%           
=======================================
  Files         214      214           
  Lines        3523     3523           
  Branches      852      852           
=======================================
  Hits         3204     3204           
  Misses        311      311           
  Partials        8        8           

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Member

@adamstankiewicz adamstankiewicz left a comment

Choose a reason for hiding this comment

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

@andrey-canon Thanks for the PR and for trying out the alpha release of design tokens in the learning MFE! Overall, I think this approach makes sense to explicitly define tokens for the hover/focus colors for the utilities so they remain theme-able. I left a question for your consideration for now.

],
"color": {
"focus": {
Copy link
Member

Choose a reason for hiding this comment

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

[curious] Hm, I wonder if it makes sense to have these new tokens explicitly named with focus given they're also being used for hover styles as well? Would it make sense to have a pretty much identical set of tokens for hover specifically? Or maybe there's a more generic name than focus here?

Copy link
Author

Choose a reason for hiding this comment

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

IMO the name should be more generic than focus, however when I wrote that I didn't have more ideas,
probably action is better and when someone needs a specific action that could be added like this

{
  "color": {
    "action":  {
        "general": {...},
        "focus": {...},
        "hover": {...},
....
      }
  }
}

where general would be this case, that is used in focus and hover

Copy link
Member

@adamstankiewicz adamstankiewicz Feb 15, 2023

Choose a reason for hiding this comment

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

@andrey-canon I think your proposed approach above is reasonable!

nit: just personal preference, but perhaps default in favor of general? 🤔

Also, I'm wondering if it'd be worthwhile to "namespace" these tokens under a "utilities" property, e.g.:

{
  "color": {
      "utilities": {
          "action":  {
              "default": {...},
              "focus": {...},
              "hover": {...}
          }
      }
  }
}

such that the resulting CSS variables are perhaps more like:

var(--pgn-color-utilities-action-default-*)

Copy link
Author

Choose a reason for hiding this comment

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

@adamstankiewicz I applied in this commit the first approach and this commit contains the utilities approach however I'm not sure about adding the namespace since that makes me feels those variables will only be used in the utility-classes file, right now is true, but probably, those will be used in other places in the future, so I think a general name will fit better

Copy link
Member

Choose a reason for hiding this comment

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

@andrey-canon Totally a valid concern! That said, because these tokens are already defined specifically in the utilities folder, it would indicate that they'll only be used relevant to utility classes. If these new tokens are more general purpose than just the utility classes, then perhaps they should be created outside of the utilities folder in favor of tokens/global/color.json?

Copy link
Author

Choose a reason for hiding this comment

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

@adamstankiewicz I agree with moving that to global folder, in that way, the variable scope is not limited

Copy link
Member

Choose a reason for hiding this comment

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

+1 sounds good here.

Copy link
Author

Choose a reason for hiding this comment

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

applied in this commit

Copy link
Member

@adamstankiewicz adamstankiewicz left a comment

Choose a reason for hiding this comment

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

@andrey-canon Oh, worth noting, related to the new tokens you're adding... we recently merged in a PR that added a type attribute to all tokens based on the W3C spec for design tokens. Do you mind adding a type property to your new tokens as well? 😄

const parent = `.bg-${type}${item === 'base' ? '' : `-${item}`}`;
const action = token.name.replace(type, `utilities-action-default-${type}`);
Copy link
Member

Choose a reason for hiding this comment

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

[question/curious] If in the future we did have utilities-action-hover-* and/or utilities-action-focus-* in the future, how would the hardcoded default here in bgVariant and textEmphasisVariant pull in hover and/or focus instead?

Copy link
Author

@andrey-canon andrey-canon Feb 15, 2023

Choose a reason for hiding this comment

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

I think that will depends on the implementation, some examples

if a helper/util function is created, that method could replace that line

function getActionVariablebyToken(token, action ="default") {
  const { attributes: { type} } = token;
  return token.name.replace(type, `utilities-action-${action}-${type}`);
}

if current function is modified

function bgVariant(token) {
  const { attributes: { type, item } } = token;
  const parent = `.bg-${type}${item === 'base' ? '' : `-${item}`}`;
  const focus = token.name.replace(type, `utilities-action-focus-${type}`);
  const hover = token.name.replace(type, `utilities-action-hover-${type}`);
  return `${parent} {
  background-color: ${`var(--${token.name})`} !important;
}

a${parent}:hover,
a${parent}:focus,
button${parent}:hover{
  background-color: ${`var(--${hover})`}  !important;
}
button${parent}:focus {
  background-color: ${`var(--${focus})`}  !important;
}

`;
}

Copy link
Member

Choose a reason for hiding this comment

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

@andrey-canon Thanks for the example here. I guess my bigger concern here is that we have to hardcode a string here to match the JSON schema exactly rather than being able to infer the token name for the hover/focus color instead. For example, what if the JSON schema decides to switch "action" ➡️ "actions", we'd have to remember to make the identical change here to account for that.

That said, I'm not sure finding a solution to that is worth the lift right now unless you see an obvious way around it; I'd be OK with deferring this particular issue. Thoughts?

Copy link
Author

Choose a reason for hiding this comment

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

@adamstankiewicz I think a reference in the color will be necessary, something like

{
  "color": {
    "primary": {
      "base": { "value": "#0A3055", "type": "color", "source": "$primary" },
      "100": {
        "value": "{color.primary.base}",
        "type": "color",
        "source": "$primary-100",
        "modify": [{ "type": "mix", "otherColor": "white", "amount": "0.94" }]
        "actions": {
          "default": "{color.action.default.primary.base}"
        }
      }
  }
}

and then try to get the action from the token, however, right now, I didn't have the solution I will try to find it out

Copy link
Author

Choose a reason for hiding this comment

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

@adamstankiewicz please check this commit

some experiments:

  1. I tried to use the name instead of path, however the value returned was just the last part, example,
color.json
        "actions": {
          "default": "{color.action.default.secondary.100.name}"
        }

result
        "actions": {
          "default": "100"
        }
  1. I tried to use a transformer instead of this line
    token.actions = {"default": `var(--pgn-${token.actions.default.join('-')})`};

however the aliasing didn't work for colors with explicit values

config json

    "dark": {
      "base": {
        "value": "#273F2F",
        "type": "color",
        "source": "$dark",
        "actions": {
          "default": "{color.action.default.dark.base.path}"
        }
      },

transform

        "actions": {
          "default": "{color.action.default.dark.base.path}"
        }

register
        "actions": {
          "default": ["color", "action", "default", "dark", "base"]
        }

if I set value to something like {color.primary.base} the register and transform results are the same

Copy link
Contributor

@brian-smith-tcril brian-smith-tcril left a comment

Choose a reason for hiding this comment

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

Overall this is looking really great! I left a couple (somewhat nitpicky) comments, but nothing that involves functionality changes or that I'd consider a blocker.

/**
* Implements bg-variant mixin from bootstrap. Creates utility classes for background colors based on theme color.
*/
function bgVariant(token) {
const { attributes: { type, item }, value } = token;
const { attributes: { type, item }, actions } = token;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const { attributes: { type, item }, actions } = token;
const { attributes: { type, item }, name, actions } = token;

const parent = `.bg-${type}${item === 'base' ? '' : `-${item}`}`;
return `${parent} {
background-color: ${value} !important;
background-color: ${`var(--${token.name})`} !important;
Copy link
Contributor

Choose a reason for hiding this comment

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

combined with the previous suggestion we could then just have

Suggested change
background-color: ${`var(--${token.name})`} !important;
background-color: ${`var(--${name})`} !important;

const parent = `.text-${type}${item === 'base' ? '' : `-${item}`}`;
return `${parent} {
color: ${value} !important;
color: ${`var(--${token.name})`} !important;
Copy link
Contributor

Choose a reason for hiding this comment

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

same as previous comment about name from bgVariant

const className = `.border-${type}${item === 'base' ? '' : `-${item}`}`;
return `${className} {
border-color: ${value} !important;
border-color: ${`var(--${token.name})`} !important;
Copy link
Contributor

Choose a reason for hiding this comment

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

same as previous comment about name from bgVariant

@andrey-canon
Copy link
Author

Overall this is looking really great! I left a couple (somewhat nitpicky) comments, but nothing that involves functionality changes or that I'd consider a blocker.

Thanks for the suggestion, it was already addressed in the last commit

@adamstankiewicz
Copy link
Member

adamstankiewicz commented Feb 24, 2023

@andrey-canon [inform] We just merged #2069, which refactors the design tokens into core and themes/light folders to help future proof the JSON files to support additional theme variants in the future (e.g., dark mode). Unfortunately, these changes are likely to cause conflicts on this PR.

Also, I'm a bit concerned that we're relying on computed properties like .path in the token source files as opposed to just the token alias itself. I pulled down your branch and plan to poke around more in depth later this afternoon to try to see if there's any alternative ways of thinking about this approach.

@andrey-canon
Copy link
Author

@adamstankiewicz I have already resolved all conflicts and also I have made some extra changes to avoid using path, please check last commit a let me know your thoughts about this approach

@mphilbrick211 mphilbrick211 added the needs test run Author's first PR to this repository, awaiting test authorization from Axim label Mar 10, 2023
@e0d
Copy link

e0d commented Mar 10, 2023

@adamstankiewicz and @brian-smith-tcril as @andrey-canon is a new contributor to this repository, actions must be approved for the tests to run. If you see the actions awaiting approval, and the code is safe, please approve to reduce wait time for feedback.

@e0d e0d removed the needs test run Author's first PR to this repository, awaiting test authorization from Axim label Mar 13, 2023
@mphilbrick211
Copy link

Hi @adamstankiewicz! Could you please review and merge if this is ready-to-go? Thanks!

@mphilbrick211 mphilbrick211 added the needs test run Author's first PR to this repository, awaiting test authorization from Axim label Apr 11, 2023
@e0d e0d removed the needs test run Author's first PR to this repository, awaiting test authorization from Axim label Apr 14, 2023
@mphilbrick211
Copy link

Hi @andrey-canon! Some branch conflicts have popped up. Would you mind taking a look? Thanks!

CC: @adamstankiewicz for review/merge.

@mphilbrick211 mphilbrick211 added the needs test run Author's first PR to this repository, awaiting test authorization from Axim label Apr 25, 2023
Copy link
Contributor

@viktorrusakov viktorrusakov left a comment

Choose a reason for hiding this comment

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

LGTM!

@adamstankiewicz
Copy link
Member

@andrey-canon Thanks for your patience in getting this re-reviewed/merged! Appreciate your contribution 😄

@adamstankiewicz adamstankiewicz merged commit f5f4921 into openedx:alpha Apr 26, 2023
@openedx-webhooks
Copy link

@andrey-canon 🎉 Your pull request was merged! Please take a moment to answer a two question survey so we can improve your experience in the future.

@edx-semantic-release
Copy link
Contributor

🎉 This PR is included in version 21.0.0-alpha.22 🎉

The release is available on:

Your semantic-release bot 📦🚀

@e0d e0d removed the needs test run Author's first PR to this repository, awaiting test authorization from Axim label Apr 27, 2023
monteri pushed a commit to raccoongang/paragon that referenced this pull request Aug 17, 2023
PKulkoRaccoonGang pushed a commit to raccoongang/paragon that referenced this pull request Aug 18, 2023
@edx-semantic-release
Copy link
Contributor

🎉 This PR is included in version 22.0.0-alpha.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@openedx-semantic-release-bot

🎉 This PR is included in version 23.0.0-alpha.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
open-source-contribution PR author is not from Axim or 2U released on @alpha
Projects
Archived in project
9 participants