-
Notifications
You must be signed in to change notification settings - Fork 69
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
feat: add custom variables to utility classes #2022
Conversation
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:
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. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
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 ☔ View full report in Codecov by Sentry. |
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.
@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.
tokens/src/utilities/color.json
Outdated
], | ||
"color": { | ||
"focus": { |
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.
[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?
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.
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
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.
@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-*)
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.
@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
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.
@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
?
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.
@adamstankiewicz I agree with moving that to global folder, in that way, the variable scope is not limited
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.
+1 sounds good here.
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.
applied in this commit
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.
@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? 😄
d149386
to
e1ea4bd
Compare
tokens/css-utilities.js
Outdated
const parent = `.bg-${type}${item === 'base' ? '' : `-${item}`}`; | ||
const action = token.name.replace(type, `utilities-action-default-${type}`); |
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.
[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?
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.
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;
}
`;
}
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.
@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?
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.
@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
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.
@adamstankiewicz please check this commit
some experiments:
- 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"
}
- I tried to use a transformer instead of this line
paragon/tokens/style-dictionary.js
Line 146 in 2a89430
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
4b127b4
to
d6a761d
Compare
626f43e
to
79f0a71
Compare
2a89430
to
a756575
Compare
6254fba
to
9184d80
Compare
a756575
to
4a567b1
Compare
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.
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.
tokens/css-utilities.js
Outdated
/** | ||
* 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; |
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.
const { attributes: { type, item }, actions } = token; | |
const { attributes: { type, item }, name, actions } = token; |
tokens/css-utilities.js
Outdated
const parent = `.bg-${type}${item === 'base' ? '' : `-${item}`}`; | ||
return `${parent} { | ||
background-color: ${value} !important; | ||
background-color: ${`var(--${token.name})`} !important; |
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.
combined with the previous suggestion we could then just have
background-color: ${`var(--${token.name})`} !important; | |
background-color: ${`var(--${name})`} !important; |
tokens/css-utilities.js
Outdated
const parent = `.text-${type}${item === 'base' ? '' : `-${item}`}`; | ||
return `${parent} { | ||
color: ${value} !important; | ||
color: ${`var(--${token.name})`} !important; |
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.
same as previous comment about name
from bgVariant
tokens/css-utilities.js
Outdated
const className = `.border-${type}${item === 'base' ? '' : `-${item}`}`; | ||
return `${className} { | ||
border-color: ${value} !important; | ||
border-color: ${`var(--${token.name})`} !important; |
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.
same as previous comment about name
from bgVariant
Thanks for the suggestion, it was already addressed in the last commit |
@andrey-canon [inform] We just merged #2069, which refactors the design tokens into Also, I'm a bit concerned that we're relying on computed properties like |
fa0910a
to
5d7c354
Compare
@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 |
@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. |
Hi @adamstankiewicz! Could you please review and merge if this is ready-to-go? Thanks! |
5d7c354
to
6e47d3a
Compare
Hi @andrey-canon! Some branch conflicts have popped up. Would you mind taking a look? Thanks! CC: @adamstankiewicz for review/merge. |
cd24bf1
to
aac2cea
Compare
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.
LGTM!
@andrey-canon Thanks for your patience in getting this re-reviewed/merged! Appreciate your contribution 😄 |
@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. |
🎉 This PR is included in version 21.0.0-alpha.22 🎉 The release is available on: Your semantic-release bot 📦🚀 |
🎉 This PR is included in version 22.0.0-alpha.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
🎉 This PR is included in version 23.0.0-alpha.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
🎉 This PR is included in version 23.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
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
example
app?wittjeff
andadamstankiewicz
as reviewers on this PR.Post-merge Checklist